为什么不在我的c ++代码中加倍自由错误?

时间:2012-07-08 02:10:16

标签: c++ double-free

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;
    }

只有测试用例一,程序运行没有错误,但如果我添加测试二,这个程序将有双重免费错误。我不知道这个错误是怎么发生的?

3 个答案:

答案 0 :(得分:3)

你只是在额外测试中遇到问题的可能原因是它有一个新的内存分配。

许多malloc / free new / delete库会在双重释放期间破坏其数据结构。在下次分配或自由操作之前,可能不会注意到此损坏。这将是你的考验二。

有些库甚至可以无误地运行。我相信某些版本的Windows实现了一个相当慢但强大的内存堆处理程序作为兼容性选项,以便不会崩溃那些有bug但很幸运的旧软件。

答案 1 :(得分:2)

Handle的析构函数被调用两次。它在_p上调用delete。在这两种情况下,_p都指向a的单个实例。双倍免费。

答案 2 :(得分:1)

我不知道为什么你的一个测试会导致问题而另一个没有。两者都错了。 Handle如果没有分配指针,则不应释放指针。那只是在寻找麻烦。