g ++版本为g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-50)
我的测试代码如下
#include <iostream>
using namespace std;
class Handle{
public:
Handle(int *p, int u):_p(p),use(u){}
~Handle(){cout << "delete" << endl; delete _p;}
void display(){cout << "value : " << *_p << ", use : " << use << endl;}
private:
int *_p;
int use;
};
int main()
{
//Test case one
{
int *i = new int(10);
Handle *h = new Handle(i, 2);
Handle *h1 = new Handle(i, 100);
h->display();
h1->display();
delete h;
delete h1;
//call ~Handle() two times, means free double times, why don't runtime error??
}
//Test case two
{
int *a = new int(11);
Handle h2(a, 23);
Handle h3(a, 33);
h2.display();
h3.display();
//in this case, will double free error
}
cout << "ok" << endl;
return 0;
}
只有测试用例一,程序运行没有错误,但如果我添加测试二,这个程序将有双重免费错误。我不知道这个错误是怎么发生的?
答案 0 :(得分:3)
你只是在额外测试中遇到问题的可能原因是它有一个新的内存分配。
许多malloc / free new / delete库会在双重释放期间破坏其数据结构。在下次分配或自由操作之前,可能不会注意到此损坏。这将是你的考验二。
有些库甚至可以无误地运行。我相信某些版本的Windows实现了一个相当慢但强大的内存堆处理程序作为兼容性选项,以便不会崩溃那些有bug但很幸运的旧软件。
答案 1 :(得分:2)
Handle的析构函数被调用两次。它在_p上调用delete。在这两种情况下,_p都指向a的单个实例。双倍免费。
答案 2 :(得分:1)
我不知道为什么你的一个测试会导致问题而另一个没有。两者都错了。 Handle
如果没有分配指针,则不应释放指针。那只是在寻找麻烦。