如何判断是否删除函数返回的指针

时间:2012-07-21 09:58:13

标签: c++ memory-leaks

考虑一个返回Type*的函数,因此看起来它可以在其定义中分配Type,但你无法确定(有很多函数,你不要没有时间阅读他们的定义。

如何判断是否应该删除返回的指针?例如,这是类型:

struct MyStruct
{
    MyStruct(void) { cout << "Created.\n"; }
    ~MyStruct(void) { cout << "Deleted.\n"; }
};

这就是功能:

MyStruct* Func1(void)
{
    return (new MyStruct());
}

Func1分配了一个指针,您应该稍后取消分配它。但也许定义是别的,指针不应该是delete d。

我的问题是:如何判断是否删除指针?例如:指针可能是静态的吗?

MyStruct* Func2(void)
{
    static MyStruct* ms = &MyStruct();
    return ms;
}

取消分配此指针会导致整个程序崩溃。

提前致谢。

4 个答案:

答案 0 :(得分:8)

无法以编程方式检查此内容。 1 作为程序员,您需要了解哪些内容需要删除,哪些内容不需要删除。

更一般地说,这是通过在C ++中传递原始指针的一个原因经常被不满。 Smart pointers通常用于管理动态分配的内存。

<小时/> <子> 1。至少,不是一种强大的平台无关的方式。

答案 1 :(得分:7)

  

如何判断是否应删除返回的指针?

你不能,这就是为什么使用原始指针来管理内存是一个非常糟糕的主意。如果一个对象需要删除,那么应该总是使用智能指针自动完成。

这也有一个好处,即动态对象一旦完成就会被删除,即使抛出异常也是如此。

std::unique_ptr<MyStruct> Func1()
{
    return std::unique_ptr<MyStruct>(new MyStruct);
}

void do_something()
{
    auto thing = Func1();
    do_something_with(thing);

    // The object is automatically deleted here
    // even if the function threw an exception.
}

如果您被迫使用设计糟糕的库,其函数返回指针可能需要删除,也可能不需要删除,那么您唯一的选择是阅读文档或找到更好的库。最好立即将需要删除的指针分配给智能指针,这样至少可以保证异常安全。

答案 2 :(得分:1)

事实:如果您没有时间阅读API上的文档,那么您将遇到错误。

归结为函数总是做出许多假设的原则,所有这些都由不同的机制强制执行:

  1. 有些是由编译器强制执行,通常是通过类型。例如,如果函数必须假定它可以写入某个参数,则其类型将为非const,并且传递const参数将导致编译器错误。这是防止错误的最佳方法。返回智能指针是一种为指针所有权提供编译器实施的方法,因此不需要文档。这就是为什么我们更喜欢void*上的模板或基类。
  2. 有些是通过惯例或惯例暗示的。同样,这意味着您不需要阅读文档以符合函数的假设,因为对任何有能力的程序员来说都应该是显而易见的。例如,如果C ++函数要求网格的行或列,则可以预期它是基于0的。这是惯例。或者对于您的情况,如果函数返回引用,则按惯例暗示调用者不应删除该对象。
  3. 除非通过文档,否则仍然无法执行许多假设。例如,您无法知道该函数是否将执行边界检查或接受NULL指针。作为API开发人员,如果可以的话,应该避免这种情况,但是在面对它时,你不能忽视文档。
  4. 作为C ++开发人员,我们尽可能努力尽可能地使用#1,但其他人无法完全避免。

答案 3 :(得分:0)

我完全赞同Mike和Oli,只有一个补充:如果库写得很好,那么可能有一些标准用来指出你究竟是什么时候你是一个函数返回指针的所有者(这意味着你必须删除它)。这可以通过命名来完成,或者函数属于某个类/命名空间。在这种情况下,您可以避免阅读每个函数的函数定义。