在我的大学里,有一个用C ++进行的实际编程测试 - 而且我坚持一个例子,我不确定这个问题是否有效并且可以正确完成。
(简单)任务:
完成Person
的析构函数,以便再次释放已分配的name
在main函数中,将//???
替换为释放先前分配的内存所需的语句
起初,这些任务对我来说似乎微不足道:对于析构函数,只需编写delete[] name
并在main函数中使用delete[] friends
。据推测,这也是本例作者的意思。
然而
此代码示例中似乎存在缺陷,导致内存泄漏以及析构函数被多次调用。
person类没有赋值operator =
,这意味着现有的Person对象(例如maria
)被分配给main函数中friends
数组中的插槽,内部已分配{ {1}}未被复制。所以两个对象现在共享相同的内部name
指针!此外,指向先前驻留在所述数组槽中的char*
名称的指针永久丢失,导致不可避免的内存泄漏。
当调用Person
时 - 数组中的对象被销毁 - 导致他们的析构函数被调用并释放他们的delete[] friends;
成员。但是,当程序结束时,name
范围内的本地Person对象被破坏 - 当然它们的main
成员仍然指向之前已经释放的内存。
实际问题:
...
name
答案 0 :(得分:5)
你是对的。您可以通过仅在指定位置进行更改来修复它,但它们会变得相当极端:
用析构函数替换析构函数中的//...
:
delete[] name;
}
Person& operator=(const Person& other)
{
if (this != &other) {
delete[] name; // not completely exception-safe!
name = new char[strlen(other.name)+1];
strcpy(other.name,name);
}
return *this;
另一个严重的问题是使用重新排序参数的新定义重新定义标准函数(strcpy
)。
(另请参阅:SQL注入攻击,它还会导致现有的语法元素对,频繁的引号和括号与插入的语法元素重新配对)
答案 1 :(得分:2)
Person
肯定需要赋值运算符,请记住Rule Of Three。friends
数组中的对象分配的内存和双重删除由自动Person
对象分配的内存。答案 2 :(得分:-1)
对于每一个新的应该有一个删除[]。