gpt4 book ai didi

c++ - 为什么在引用传递包含指针成员的类对象时多次调用析构函数?我该如何纠正这个问题?

转载 作者:搜寻专家 更新时间:2023-10-31 02:13:16 24 4
gpt4 key购买 nike

我有一个表单类

class A
{
int **a;
//other members
}

在某些函数中,我通过引用传递了一个类 A 的对象,例如 obj

void func(A &o); //function declaration

func(std::ref(obj)); //function call

但是,我收到以下错误 - double free or corruption (!prev)

根据链接的问题,这是因为指针成员的析构函数被多次调用,复制构造函数在复制时被多次调用的结果,导致尝试重新分配已经释放的内存。但是,当我通过引用传递完整的对象时,为什么会发生这种情况?不应该简单地复制整个对象的地址吗?

以上述链接和 here 中给出的形式实现复制构造函数的建议无济于事,因为它们涉及在复制对象时分配新的内存量,而我想传递对象,并作为结果指针成员,通过引用。

我查看了 thisthis ,它们可能是重复项,但它们并没有解决我的问题。

根据其他一些答案,我还尝试将析构函数实现为

~A()
{
delete[] a;
}

~A()
{
if(a)
{
delete[] a;
}
}

但都没有解决问题。

最佳答案

尝试 A(A const&)=delete;A(A&&o):a(o.a){a=nullptr;} .这会删除您的复制构造函数并写入一个非分配移动构造函数。

如果您尝试复制类的实例,已删除的复制构造函数会给您带来编译时错误。在您的情况下,这会导致破坏崩溃,这似乎是个好主意。

只要返回值是隐式或显式 ( std::move ) 移出的,移动构造函数就可以让您从函数中安全地返回类的实例。

还考虑

A& operator=(A&&o) { 
if (this==&o) return *this;
std::swap(a,o.a);
delete[] o.a;
o.a=nullptr;
return *this;
}
A& operator=(A const&o)=delete;

这让您可以分配给 A来自另一个搬自A .

在编写析构函数时应该处理移动/复制分配/构造的事实称为五规则。

您应该避免编写其中任何一个的事实称为零规则。

为避免编写它们,请替换您的 aunique_ptr<int[]> .现在它会为您生成移动操作和析构函数,并自动删除您的复制操作。

关于c++ - 为什么在引用传递包含指针成员的类对象时多次调用析构函数?我该如何纠正这个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41647015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com