【问题标题】:Incorrect memory leak in purify?净化中不正确的内存泄漏?
【发布时间】:2012-07-31 04:34:49
【问题描述】:

我在 Solaris 中运行的代码上运行了 purify,它显示了很多内存泄漏。 但是我检查了代码,大多数泄漏似乎都是无效的。

例如,

文件 1.cpp

Obj* getMyObj()
{
    Obj* obj = NULL;
    if(condition)
    {
        obj = new Obj();   //Purify is reporting leak here
        //Fill obj
    }

    ...
    return obj;
}

文件2.cpp

void myfunc()
{
    Obj* myobj = getMyObj();

   if(myobj == NULL)
       return;
    ...
    ...

    delete myobj;    //The object is deleted here
}

即使对象在File2.cpp 中被正确销毁,为什么 purify 会在File1.cpp 中报告泄漏?

编辑

NULL 检查只是一个错字,我更正了。

【问题讨论】:

  • 你展示了你所有的代码吗?这是一个工厂函数,您可以根据“条件”构建不同的对象吗?在这种情况下,Obj 类是否有虚拟析构函数?
  • @NiklasKarlsson - 这不是工厂函数。但是,Obj 类有一个虚拟析构函数。

标签: c++ delete-operator purify


【解决方案1】:

即使对象在 File2.cpp 中被正确销毁,[...]

这个假设是错误的。

Obj* myobj = getMyObj();

如果getMyObj 真的创建了一个对象,它不会返回一个空指针。也就是说后面if中的条件为真,然后函数立即返回。

if(myobj)
    return;

在该函数中不再执行代码,因此它永远不会被销毁。

我建议使用智能指针而不是这种手动管理,因为这种错误会消失。对于 C++11,你可以使用std::unique_ptr,否则你可以使用std::auto_ptr,如果你小心的话。

【讨论】:

  • @DeadMG - 如果他无权访问boostC++11,他会怎么做?
  • @cppcoder 编写您自己的智能指针类。像 boost 的 shared_ptr 这样的东西很简单,尽管你不太可能像 boost 开发者那样做得很好。
  • @jahhaj shared_ptr 远非直截了当,除非你的意思是写一个有问题的很直截了当。 auto_ptr 很好,如果你小心点,不要把它丢在容器等上。
  • @R.Martinho Fernandes 嗯,你在想什么样的错误?引用计数的智能指针是书籍等中很好地涵盖的主题。
  • @jahhaj:std::auto_ptr 比自己编写要好得多。
【解决方案2】:
if(myobj)
   return;

对象创建后返回继续,删除从未执行

你需要修改代码:

-if(myobj)
+if(myobj==NULL)

【讨论】:

    【解决方案3】:

    file1.cpp

    Obj* getMyObj();
    

    这个函数有点不安全,因为函数的调用者需要知道他必须删除返回的对象,但从函数中并不清楚这是必要的

    更好的是使用像 shared_ptr 这样的智能指针而不是原始指针,这样就可以清楚地知道返回的对象是在堆上分配的,以及它是如何被销毁的(如果分配的话)。

    std::shared_ptr<Obj> getMyObj();
    

    【讨论】:

    • 我不推荐shared_ptr,因为它的语义非常专业且不是很通用。
    猜你喜欢
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2017-03-06
    • 2013-01-23
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多