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

发布于 2024-12-23 10:36:01 字数 763 浏览 2 评论 0原文

我有一个名为“Packet”的类,具有以下解构:

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时,该对象肯定被定义了。

这个错误的真正含义是什么?

I have a class named "Packet" with this destruct:

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

The RequestPtr looks like:

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

Problem is when delete req; and consequently ~Request() {} are executed, I get this error:

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

At first I thought that maybe req were deleted somewhere else and when it want to execute delete req;, obviously there is no req. However as you can see, there is a if statement which checks if the req is defined or not. So definitely when it want to delete req, the object is defined.

What does this error really mean?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吾家有女初长成 2024-12-30 10:36:01

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

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

如果 req 不为 NULL,则检查 if (req) 将为 true,而不是如果它已被释放(如 Mat 在问题评论中所述)。

如果您在类的某些其他方法中删除 req,则必须将 req 设置为 NULL:

delete req;
req = 0;

否则将发生双重释放。

只是要注意,对 NULL 指针调用 delete 没有任何效果,因此以下内容是安全的:

delete req;
req = 0;
delete req; // No need to check 'if (req)'

The default copy constructor and assignment operator are used in class Packet and you have a pointer to dynamically allocated memory.

If a copy of Packet is made and the original object destroyed a double deallocation will occur when the second object is destroyed. Either implement the copy constructor and assignment operator or prevent copying of Packet by declaring them private.

The check if (req) will be true if req is not NULL, not if it has already been deallocated (as stated by Mat in comment to question).

If you delete req in some other method of the class you must set req to NULL:

delete req;
req = 0;

Or a double deallocation will occur.

Just to note that calling delete on a NULL pointer has no effect, so the following is safe:

delete req;
req = 0;
delete req; // No need to check 'if (req)'
最佳男配角 2024-12-30 10:36:01

正确的删除方法是,

delete req;
req = 0;

否则删除后req将是一个悬空指针。

The correct way to delete is

delete req;
req = 0;

otherwise req will be a dangling pointer after deletion.

几度春秋 2024-12-30 10:36:01

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

// 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,这样就不会再发生同样的事情。

I use this macro in classes that are responsible for cleaning up other objects:

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

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

usage in cpp file:

~Packet() {
    SAFE_DELETE(req)
}

It checks if the pointer is non-NULL, deletes pointer if so, and sets it to NULL so that the same thing doesn't happen again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文