删除对象时双重释放或损坏

时间:2012-01-01 13:05:21

标签: c++ destructor glibc

我有一个名为“Packet”的类,带有这个destruct:

class Packet
{
   ...
   RequestPtr req;
   ~Packet()
   {
     if (req && isRequest() && !needsResponse())
        delete req;      
     deleteData();
   }
};

RequestPtr看起来像:

typedef Request* RequestPtr;
class Request
{
   ...
   ~Request() {} 
}

问题是当执行delete req;并因此执行~Request() {}时,我收到此错误:

*** glibc detected *** double free or corruption (fasttop): 0x0000000002a8a640 ***

起初我以为可能req在其他地方被删除了,当它想要执行delete req;时,显然没有req。但是正如您所看到的,有一个if语句可以检查req是否已定义。所以当它想要删除req时,就定义了该对象。

这个错误究竟意味着什么?

3 个答案:

答案 0 :(得分:4)

默认的复制构造函数和赋值运算符在类Packet中使用,并且您有一个指向动态分配的内存的指针。

如果制作了Packet的副本并且原始对象被破坏,则在第二个对象被销毁时将发生双重释放。要么实现复制构造函数和赋值运算符,要么通过声明Packet来阻止复制private

如果if (req)不为NULL,则检查req将为真,如果已经解除分配,则检查delete req(如Mat中所述,在评论中提出问题)。

如果您在类的其他方法中req,则必须将delete req; req = 0; 设置为NULL:

delete

或者会发生双重释放。

请注意,在NULL指针上调用delete req; req = 0; delete req; // No need to check 'if (req)' 无效,因此以下是安全的:

{{1}}

答案 1 :(得分:0)

正确的删除方式是

delete req;
req = 0;

否则req将在删除后成为悬空指针。

答案 2 :(得分:-1)

我在负责清理其他对象的类中使用此宏:

// place in a commonly included .h file of yours

#define SAFE_DELETE(p) \
 {if (p != NULL) \
     delete p;\
 p = NULL;}

在cpp文件中的用法:

~Packet() {
    SAFE_DELETE(req)
}

它检查指针是否为非NULL,如果是,则删除指针,并将其设置为NULL,以便不再发生同样的事情。