删除对象时双重释放或损坏
我有一个名为“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Packet
类中使用默认的复制构造函数和赋值运算符,并且您有一个指向动态分配的内存的指针。如果制作了
Packet
的副本,并且原始对象被销毁,则当第二个对象被销毁时,将发生双重释放。要么实现复制构造函数和赋值运算符,要么通过将它们声明为private
来防止复制Packet
。如果
req
不为 NULL,则检查if (req)
将为 true,而不是如果它已被释放(如 Mat 在问题评论中所述)。如果您在类的某些其他方法中
删除 req
,则必须将req
设置为 NULL:否则将发生双重释放。
只是要注意,对 NULL 指针调用
delete
没有任何效果,因此以下内容是安全的: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 ofPacket
by declaring themprivate
.The check
if (req)
will be true ifreq
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 setreq
to NULL:Or a double deallocation will occur.
Just to note that calling
delete
on a NULL pointer has no effect, so the following is safe:正确的删除方法是,
否则删除后
req
将是一个悬空指针。The correct way to delete is
otherwise
req
will be a dangling pointer after deletion.我在负责清理其他对象的类中使用这个宏:
在cpp文件中的用法:
它检查指针是否为非NULL,如果是则删除指针,并将其设置为NULL,这样就不会再发生同样的事情。
I use this macro in classes that are responsible for cleaning up other objects:
usage in cpp file:
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.