在浅拷贝后调用析构函数会出现 "Abort trap: 6" 错误
Calling destructor after shallow-copy gives "Abort trap: 6" error
所以我有一个自己实现的链表class。对于制作“深层副本”或基本上是链表副本的复制构造函数。但是对于赋值运算符,我基本上是这样做的
// assignment operator
linked_list& linked_list::operator=(const linked_list& L){
// check for self assignment
if(this != &L){
this->head=L.head;
this->sz=L.sz;
}
return *this;
}
这是一个“浅拷贝”,因此当我创建一个新的链表 b 并将其指向 a 时,b 中的更改将反映在 a 中。
但现在的问题是,当我调用一个动态分配节点的析构函数时,由于它们都指向同一个对象,并且其中一个析构函数先于另一个被调用,我收到以下错误消息。
edit.out(3537,0x106bcbdc0) malloc: *** error for object 0x7fa430c018f0: pointer being freed was not allocated
edit.out(3537,0x106bcbdc0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6
我使用 lldb 来探索任何解决方案,但我无法控制估计哪些对象的析构函数将首先被调用,以及如何防止它再次被调用。
如果你的复制构造函数和析构函数工作正常(意味着没有错误),那么赋值运算符可以很容易地使用copy / swap idiom:
#include <algorithm>
//...
linked_list& linked_list::operator=(const linked_list& L)
{
if (this != &L)
{
linked_list temp(L);
std::swap(head, temp.head);
std::swap(sz, temp.sz);
}
return *this;
}
我假设 head
和 sz
是唯一的成员。如果您有其他成员,您也需要 swap
。
简而言之,其工作方式是复制传入的 linked_list
。然后,您只需将当前对象的内部结构替换为临时副本的内部结构即可。然后临时副本与旧的内部结构一起销毁。
所以我有一个自己实现的链表class。对于制作“深层副本”或基本上是链表副本的复制构造函数。但是对于赋值运算符,我基本上是这样做的
// assignment operator
linked_list& linked_list::operator=(const linked_list& L){
// check for self assignment
if(this != &L){
this->head=L.head;
this->sz=L.sz;
}
return *this;
}
这是一个“浅拷贝”,因此当我创建一个新的链表 b 并将其指向 a 时,b 中的更改将反映在 a 中。
但现在的问题是,当我调用一个动态分配节点的析构函数时,由于它们都指向同一个对象,并且其中一个析构函数先于另一个被调用,我收到以下错误消息。
edit.out(3537,0x106bcbdc0) malloc: *** error for object 0x7fa430c018f0: pointer being freed was not allocated
edit.out(3537,0x106bcbdc0) malloc: *** set a breakpoint in malloc_error_break to debug Abort trap: 6
我使用 lldb 来探索任何解决方案,但我无法控制估计哪些对象的析构函数将首先被调用,以及如何防止它再次被调用。
如果你的复制构造函数和析构函数工作正常(意味着没有错误),那么赋值运算符可以很容易地使用copy / swap idiom:
#include <algorithm>
//...
linked_list& linked_list::operator=(const linked_list& L)
{
if (this != &L)
{
linked_list temp(L);
std::swap(head, temp.head);
std::swap(sz, temp.sz);
}
return *this;
}
我假设 head
和 sz
是唯一的成员。如果您有其他成员,您也需要 swap
。
简而言之,其工作方式是复制传入的 linked_list
。然后,您只需将当前对象的内部结构替换为临时副本的内部结构即可。然后临时副本与旧的内部结构一起销毁。