微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C删除指针数组 – 双重释放或损坏

这只是一个了解继承如何工作的测试项目. Cat是Mammal的子类,它又是Animal的子类.
int main()
{
    Cat* cat1 = new Cat("nosy grey",1.0d,3);
    Cat* cat2 = new Cat("purply green",2.0d,4);

    Cat* cats[] = {cat1,cat2};

    delete [] cats;
 }

所以我不能真的这样做,因为我得到了这个.

*** Error in `/home/max/git/info-2-ss/blatt3/Aufgabe2/main.exe': double free or corruption (out): 0x00007fff55fd7b10 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x80a46)[0x7f3a07452a46]
/home/max/git/info-2-ss/blatt3/Aufgabe2/main.exe[0x40178e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f3a073f3ea5]
/home/max/git/info-2-ss/blatt3/Aufgabe2/main.exe[0x400d39]

当我的构造函数和析构函数调用输出,所以当我的Cats被创建时,我会得到这样的结果:

Called ctor of Animal with age: 3
Called ctor of Mammal with hairLength: 1
Called ctor of Cat with eyecolor: nosy grey

当我改变我的代码时,它会读取:

delete [] *cats;

然后我会期待我的dtors会像每个猫一样被召唤:

Called dtor of Cat
Called dtor of Mammal 
Called dtor of Animal

相反,我得到这一行:

Called dtor of Cat

摘要
我怎样才能有效地删除我的数组,以便我的所有dtors都被调用

解决方法

只有从new … []获得此数组时,才应在数组上使用delete []!像这样:
Cat * cats = new Cat[2];
delete [] cats;

以上是正确的.但请注意,当然,在这种情况下,您无法将参数传递给构造函数.

现在,你的情况.您没有使用new创建数组,因此您不应该删除数组本身(它位于堆栈上,而不是堆中).这就是删除[]猫崩溃的原因.接下来,* cats将数组视为指针并取消引用它,即返回此指针指向的项.对于数组,它是数组的开头:* cats与cats [0]相同.这就是为什么在第二次尝试中只删除第一项.

最后,答案是:而不是所有这些,单独删除每个项目.对于你的简单案例:

delete cat1;
delete cat2;

或者,更一般地说:

for(int i = 0; i < sizeof(cats)/sizeof(cats[0]); ++i) {
    delete cats[i];
}

这里sizeof(cats)/ sizeof(cats [0])是一个简单的技巧,通过将其大小除以元素的大小来获取数组中的项数.

通过此,您可以释放放置每个Cat对象的内存.如果您担心指针数组所在的内存 – 它位于堆栈上,这意味着它将在从函数返回时自动释放.

原文地址:https://www.jb51.cc/c/116326.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐