在C ++代码中检测双重释放

时间:2010-09-07 00:39:36

标签: c++

我有一个代码,

class foo
{
   public:
     foo(){};
     ~foo(){};
};

class bar
{
   public:
      bar(){};
     ~bar(){};

      foo& Foo()
      {
         return m_foo;
      }

  private:
      foo m_foo; 
};

int main()
{
   bar *obj = new bar;

   if( /* true condition here */ )
   {
      foo lcFoo;
      lcFoo = obj->Foo(); // forgot this
   }

   delete obj;
}

现在,当我调用“删除obj”部分时,我从glibc获得了一条双重免费消息。

请建议。

感谢。

编辑: 感谢您的评论,但这是我使用的确切代码。你认为这个问题出在foo& Foo()函数,因为它返回m_foo对象的引用,然后当代码跳转到if条件大括号,那么m_foo将被删除?

3 个答案:

答案 0 :(得分:7)

您发布的代码中没有双重免费。我怀疑foo中有一些指针资源,当复制foo时,它被复制为指针;但在delete的析构函数中是foo d。

您可能还想将if块的内容更改为

foo& lcFoo = obj->Foo();

虽然你在这里获得双重释放的事实表明问题比这更大。

答案 1 :(得分:4)

您的foo类没有正确实现Rule of Three:每次实现析构函数时,通常都表明您需要复制构造函数和复制赋值操作

我的猜测是你在foo类中有一些指针deletefoo的析构函数中,但是因为你没有实现一个副本复制foo类时的构造函数,它只是复制指针。当foo的两个实例都被破坏时,它们都会尝试free该指针,并获得错误。

但是,我建议您不要实现复制构造函数和复制赋值运算符,而是在foo中删除析构函数并使用智能指针(可能是shared_ptr)。

正如其他人已经指出的那样,你可能也想说foo &lcFoo = obj->Foo()只会隐藏更大的问题

答案 2 :(得分:1)

如果您使用的是Linux,请尝试通过Valgrind运行代码。