我想知道为什么在下面的代码中,第一次删除不会释放内存:
#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;
}输出为:
const
pA: 0x93D8008
pB: 0x93D8008
desc
desc
before double-free
desc
*** glibc detected *** ./test: double free or corruption (fasttop): 0x093d8008 ***
...我也用free()试过了,但行为是一样的。
发布于 2012-01-10 23:58:20
delete pA; // ~abc() and free (works)
puts("before double-free");
delete pA; // ~abc() and second free (crash)这些delete语句是,而不是在编写delete pB时需要的。您有一个误解,即delete pB只调用析构函数。不,它调用析构函数并释放内存。
另外,由于您已经编写了delete pB,接下来的两个delete表达式将调用undefined behavior,这意味着任何事情都可能发生:程序可能崩溃,也可能不崩溃!
请看以下主题:
发布于 2012-01-11 00:04:21
您的第一个delete会将指针呈现为无效状态。所以现在使用指针会导致未定义行为。
int* p = new int;
delete p;
delete p; //undefined behaviour根据标准,这是可以保证的(正如在第一条评论中指出的):
int* p = new int;
delete p;
p = 0;
delete p; //fine发布于 2012-01-10 23:58:39
首先,你不能free分配给new的内存,你必须使用delete。
其次,仅仅因为glibc没有立即检测到双重释放,你怎么知道 delete pB;没有释放它呢?这就是delete所做的,并且从您自己的日志记录中,您每次都会将相同的地址传递给delete。
第三:你到底想要实现什么?
https://stackoverflow.com/questions/8806189
复制相似问题