释放调用方或被调用方的内存



函数(例如"fun()")分配内存并返回指向已分配内存的指针。我该如何确保这些内存被释放。我不能在函数"fun()"中立即释放它,因为它被返回给调用者。如果fun()是library的一部分呢?它的职责是释放内存。在fopen()的情况下,内存由fclose()释放。但在我的例子中,"fun()"被反复调用。所以我不能等到结束才释放内存。

以下是C的答案,在OP承认使用c++之前发布。在该语言中,按照其他人的建议,使用RAII和智能指针。

如果函数返回已分配的内存,则调用者负责释放内存,这必须在函数的文档中说明。

如果需要更多的清理,那么free提供了,或者在库的未来版本中可能需要这样的清理,那么您应该提供一个清理函数(就像stdiofclose所做的那样)来进行释放。如果您无法预测将来是否需要额外的清理,那么最好假设它在某个时候是必要的。包装free很便宜。

可以把它看作一种对称形式:如果客户端从库中获得资源(对象),那么它最终负责将其交还给库以进行处理:

void use_the_foo_library()
{
    Foo *f = make_foo();
    if (f == NULL)
        ERROR();
    foo_do_bar(f);
    foo_do_baz(f);
    foo_destroy(f);
}

在folibb 1.0中,foo_destroy只是

void foo_destroy(Foo *p)
{
    free(p);
}

但是在2.0版本中,它可能已经变成

void foo_destroy(Foo *p)
{
    fclose(p->logfile);
    free(p);
}

等。此样式与不透明指针设计模式一致。它还使您可以在任何时候自由地使用特殊用途的内存分配器(如池分配器)替换mallocfree,而无需更改任何客户机代码。

如果是c++,不要返回原始指针到内存,而是返回一个智能指针。

,

std::shared_ptr<TypePointedTo> data = fun();

这样,当shared_ptr销毁时,它会自动为您释放内存。

或者,如果你想返回一个数组,使用一个向量,这同样会自动为你释放内存:

std::vector<BYTE> data = fun();

阅读优秀的评论,std::unique_ptr在很多情况下可能比std::shared_ptr更好。

如果是C…看看其他答案吧!

在c++中,您将返回一个智能指针,它清楚地声明(并强制)所有权已转移给调用者,并允许调用者选择如何处理它。它还提供异常安全性,如果异常(或只是早期的函数返回)导致指向资源的唯一指针超出作用域,则可以防止内存泄漏。

在c++ 03中,std::auto_ptr是最好的选择;在c++ 11中,这已被弃用,取而代之的是std::unique_ptr

C解:

如果fun()是库的一部分呢?

你的库api应该记录调用者需要释放的内存。
您还应该为它提供一个free函数,并要求库的用户调用它来释放分配。

编辑:

C + +解决方案:

既然你编辑说你正在使用c++,也许最好使用智能指针(std::tr1::shared_ptr)来自动处理内存。

如果你不能使用智能指针,使用std::vector也是一个不错的选择。

如果您需要调用对象之外的内存,那么很明显,它负责释放内存,因为您无法在调用对象中真正释放内存。它与newdelete相同,您只需要记住释放该内存。确保您记录了调用者负责内存管理的事实。

您必须记录已分配的内存,并且调用者负责释放内存。你不能自己释放它,因为你不知道调用者的意图。你会在使用前释放它。

你可以提供一个cleanUp()方法来调用并刷新内存,但这仍然依赖于调用者,并且你在何时应该调用它时增加了复杂性。

唯一真正的选择是建立一个聪明的"引用计数"机制,比如在Objective-C中(参见release和autorelease)。

最新更新