在浅拷贝后调用析构函数会出现 "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;
}

我假设 headsz 是唯一的成员。如果您有其他成员,您也需要 swap

简而言之,其工作方式是复制传入的 linked_list。然后,您只需将当前对象的内部结构替换为临时副本的内部结构即可。然后临时副本与旧的内部结构一起销毁。