防止内存泄漏(特定于案例)

时间:2010-06-21 18:46:04

标签: c++ memory-leaks

考虑以下情况:

SomeType *sptr = someFunction();
// do sth with sptr

我不知道someFunction()的内部。很明显,指向someFunction()返回的对象的指针必须是malloc'ed或者是一个静态变量。

现在,我用sptr做了一些事情,然后退出了。显然,对象仍然在堆上,这可能是泄漏源。

我该如何避免这种情况?

修改

引用是否比指针更安全。  如果我这样做,将调用SomeType的析构函数:

{
  SomeType &sref = *sptr;
}

任何见解。

6 个答案:

答案 0 :(得分:19)

您需要阅读someFunction上的文档。 someFunction需要明确定义返回指针的所有权(调用者是否拥有它并需要调用deletesomeFunction拥有它并确保对象在某个时间被破坏未来)。

如果代码没有记录它的行为,则没有安全的方法来使用它。

答案 1 :(得分:3)

戒烟是什么意思?结束这个过程?当进程被销毁时,您的堆通常会被销毁。如果您要求操作系统为您执行某些操作(例如获取文件或窗口句柄)并且未释放它,则在退出进程后只会出现泄漏漏洞。

此外,返回指针的函数需要很好地记录,它的责任是释放指针目标(如果有的话),否则,您无法知道是否需要自己删除它或者您可能意外删除它(如果你不打算这么做就是灾难)。

如果该函数的文档没有告诉您该怎么做,请检查库文档 - 有时整个库采用相同的策略,而不是在每个函数中记录它。如果你无法在任何地方找到答案,请联系作者或放弃图书馆,因为错误的可能性是不值得的,恕我直言。

根据我的经验,大多数返回指针的函数要么动态分配它,要么返回一个基于输入参数的指针。在这种情况下,由于没有参数,我敢打赌它是动态分配的,你应该在完成后删除它。但编程不应该是一个猜谜游戏。

答案 2 :(得分:0)

自我清理总是一个好习惯,不要假设操作系统会这样做;

退出应用程序时,IDE或调试器会报告内存泄漏,这是一个很好的更改。

你有什么要做的?嗯,这取决于,但通常你必须释放由someFunction()分配的内存,文档可能会帮助你,或者有一个API来释放内存,或者你必须手动使用free或delete。< / p>

最高

答案 3 :(得分:0)

图书馆应该记录下来。 要么在使用后显式删除它,要么调用一些释放方法,以确保对象(以及它指向*的任何其他资源)不会泄漏。

(给出一个选择)除非它是一个巨大的(在内存方面)对象,我宁愿选择按值返回。或者传递对函数的引用。

答案 4 :(得分:0)

如果someFunction为我返回一个对象,那么拥有像someFunctionFree这样的对函数应该是正常的,你可以调用它来释放SomeType对象的资源。所有需要的东西都应该在someFunction的文档中找到(主要是如何可以释放对象或者是否自动释放对象)。我个人更喜欢相应的释放函数(CreateObject / DestroyObject对)。

答案 5 :(得分:0)

正如其他人所指出的那样,由代码强制执行它的所有权假设的功能。这是使用所谓smart pointers

的一种方法
#include <iostream>
#include <boost/shared_ptr.hpp>

struct Foo
{ 
  Foo( int _x ) : x(_x) {}
  ~Foo() { std::cout << "Destructing a Foo with x=" << std::hex << x << "\n"; }
  int x;
};

typedef boost::shared_ptr<Foo> FooHandle;

FooHandle makeFoo(int _x = 0xDEADBEEF) {
    return FooHandle(new Foo(_x));
}

int main()
{
    {
        FooHandle fh = makeFoo();
    }
    std::cout<<"No memory leaks here!\n";

    return 0;
}