[英]Why I have to call delete on the “original” pointer?
I would like to know why in the following code the first delete won't free the memory: 我想知道为什么在下面的代码中第一次删除不会释放内存:
#include <list>
#include <stdio.h>
struct abc {
long a;
abc() {
puts("const");
}
~abc() {
puts("desc");
}
};
int main() {
std::list<abc*> test;
abc* pA = new abc;
printf("pA: 0x%lX\n", (unsigned long int)pA);
test.push_back(pA);
abc* pB = test.back();
printf("pB: 0x%lX\n", (unsigned long int)pB);
delete pB; // just ~abc()
test.pop_back();
delete pA; // ~abc() and free (works)
puts("before double-free");
delete pA; // ~abc() and second free (crash)
return 0;
}
Output is: 输出是:
const
pA: 0x93D8008
pB: 0x93D8008
desc
desc
before double-free
desc
*** glibc detected *** ./test: double free or corruption (fasttop): 0x093d8008 ***
...
I tried it with free()
also but same behavior. 我尝试了
free()
也行为相同。
delete pA; // ~abc() and free (works)
puts("before double-free");
delete pA; // ~abc() and second free (crash)
These delete
statements are not needed once you write delete pB
. 一旦编写
delete pB
就不需要这些delete
语句。 You've a misconception that delete pB
only calls the destructor. 你错误地认为
delete pB
只调用析构函数。 No, it calls the destructor and also deallocates the memory. 不,它调用析构函数并释放内存。
Also, since you've already written delete pB
, the next two further delete
expressions invoke undefined behavior , which means anything can happen : the program may or may not crash! 此外,由于您已经编写了
delete pB
,接下来的两个delete
表达式会调用未定义的行为 ,这意味着任何事情都可能发生:程序可能会也可能不会崩溃!
Have a look at these topics: 看看这些主题:
Your first delete renders the pointer to invalid state. 您的第一次删除会将指针呈现为无效状态。 So use of that pointer now leads to undefined behaviour.
因此,使用该指针现在会导致未定义的行为。
int* p = new int;
delete p;
delete p; //undefined behaviour
This is guaranteed to be fine by the standard (as pointed out in the first comment): 按标准保证这是正常的(如第一条评论中所指出的):
int* p = new int;
delete p;
p = 0;
delete p; //fine
First, you can't free
memory allocated with new
, you have to use delete
. 首先,你不能
free
分配new
内存,你必须使用delete
。
Secondly, just because glibc doesn't detect the double free immediately, how do you know delete pB;
其次,只是因为glibc没有立即检测到双重释放,你怎么知道
delete pB;
isn't freeing it? 是不是正在释放它? That's what
delete
does, and from your own logging you're passing the same address to delete
each time. 这就是
delete
操作,并且从您自己的日志记录中,您每次都要传递相同的地址进行delete
。
Thirdly: what are you actually trying to accomplish? 第三:你究竟想要完成什么?
It's just an indiosyncracy of your compiler/platform that you had to call delete
twice on pA
before glibc
complained ... for instance, on my current platform, which is OSX 10.6.8 with gcc
version i686-apple-darwin10-gcc-4.2.1, I get the following output: 这只是你的编译器/平台的indiosyncracy你不得不打电话给
delete
两次pA
前glibc
抱怨......比如,我现在的平台,这是OSX 10.6.8上gcc
版本的i686-苹果darwin10-GCC-4.2 .1,我得到以下输出:
const
pA: 0x100100080
pB: 0x100100080
desc
desc
test(14410) malloc: *** error for object 0x100100080: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap
So you can see the first call to delete
on pA
, which by the standard results in undefined behavior since you didn't set the pointer to NULL
or 0
, did get caught as an attempt to deallocate already deallocated memory by the C++ run-time on my platform. 所以你可以在
pA
上看到第一次调用delete
,由于你没有将指针设置为NULL
或0
,标准会导致未定义的行为,因为尝试通过C ++运行时释放已经释放的内存在我的平台上。
Since the results of the double-delete are "undefined behavior", it's really up to the implementation and platform on what happens. 由于双删除的结果是“未定义的行为”,因此实际上取决于所实现的实现和平台。
You may be able to detect allocation/deallocation memory errors quicker if you use the link against the glibc memory consistency checker by compiling with the -lmcheck
flag. 如果通过使用
-lmcheck
标志进行编译来使用针对glibc内存一致性检查程序的链接,则可以更快地检测分配/释放内存错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.