在我的大學裏,有一個用C++進行的實際編程測試 - 而且我堅持一個例子,我不確定這個任務是否有效,正確完成。C++測試示例中可能存在的邏輯缺陷
的(簡單)的任務:
完成的
Person
析構函數,使分配name
再次釋放在主函數中,有需要的語句來替換
//???
釋放先前分配的內存
起初,這些任務對我而言似乎微不足道:對於析構函數,只需編寫delete[] name
並在主函數中使用delete[] friends
即可。據推測,這也是這個例子的作者意味着我們要做的。
然而:
似乎有在該代碼示例中的缺陷,這會導致內存泄漏以及析構函數被調用一次以上。
的人類沒有分配operator =
,這意味着與現有的Person對象如maria
被分配給時隙的主要功能的friends
陣列中,內部分配name
s的不被複制。因此,兩個對象現在共享相同的內部指針char*
!此外,先前駐留在所述陣列插槽中的指向名稱Person
的指針永久丟失,導致不可避免的內存泄漏。
As delete[] friends;
被調用 - 數組中的對象被銷燬 - 導致它們的析構函數被調用並釋放它們的name
成員。然而,當程序結束時,main
範圍內的本地Person對象被破壞 - 當然,它們的name
成員仍然指向之前已經釋放的內存。
實際的問題:
- 這是測試例子有缺陷,還是我失去了一些東西?
- 如果完全堅持執行給定的任務(只改變析構函數的實現,並在主函數的註釋部分插入新代碼),上面列出的問題是否可以解決?
..
#include <iostream>
using namespace std;
int strlen(const char *str) {
if (str==0) return 0;
int i=0;
for (; str[i]; ++i);
return i;
}
void strcpy(const char *src, char *dest) {
if (src==0 || dest==0) return;
int i=0;
for (; src[i]; ++i) dest[i]=src[i];
dest[i]=’\0’;
}
class Person {
char *name;
public:
Person(const char *str = "Susi") {
name = new char[strlen(str)+1];
strcpy(str,name);
}
Person(const Person &p) {
name = new char[strlen(p.name)+1];
strcpy(p.name,name);
}
~Person() {
//...
}
void change() {
name[4]='e';
}
ostream &print(ostream &o) const {
o<<name;
return o;
}
};
int main() {
Person maria("Maria"), peter("Peter"), franz("Franz"), luisa("Luisa");
Person mary(maria);
Person luise;
Person p(luise);
Person *friends= new Person[7];
friends[0]=maria;
friends[1]=peter;
friends[2]=franz;
friends[3]=luisa;
friends[4]=mary;
friends[5]=luise;
friends[6]=p;
friends[5]=luisa;
friends[3].change();
friends[4].change();
for (int i=0; i<7; ++i) {
friends[i].print(cout);
cout<<endl;
}
//???
return 0;
}
你是對的。 [三項規則](http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29)被侵犯。 –