函数(例如"fun()")分配内存并返回指向已分配内存的指针。我该如何确保这些内存被释放。我不能在函数"fun()"中立即释放它,因为它被返回给调用者。如果fun()是library的一部分呢?它的职责是释放内存。在fopen()的情况下,内存由fclose()释放。但在我的例子中,"fun()"被反复调用。所以我不能等到结束才释放内存。
以下是C的答案,在OP承认使用c++之前发布。在该语言中,按照其他人的建议,使用RAII和智能指针。
如果函数返回已分配的内存,则调用者负责释放内存,这必须在函数的文档中说明。
如果需要更多的清理,那么free
提供了,或者在库的未来版本中可能需要这样的清理,那么您应该提供一个清理函数(就像stdio
对fclose
所做的那样)来进行释放。如果您无法预测将来是否需要额外的清理,那么最好假设它在某个时候是必要的。包装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);
}
等。此样式与不透明指针设计模式一致。它还使您可以在任何时候自由地使用特殊用途的内存分配器(如池分配器)替换malloc
和free
,而无需更改任何客户机代码。
如果是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
也是一个不错的选择。
如果您需要调用对象之外的内存,那么很明显,它负责释放内存,因为您无法在调用对象中真正释放内存。它与new
和delete
相同,您只需要记住释放该内存。确保您记录了调用者负责内存管理的事实。
您必须记录已分配的内存,并且调用者负责释放内存。你不能自己释放它,因为你不知道调用者的意图。你会在使用前释放它。
你可以提供一个cleanUp()方法来调用并刷新内存,但这仍然依赖于调用者,并且你在何时应该调用它时增加了复杂性。
唯一真正的选择是建立一个聪明的"引用计数"机制,比如在Objective-C中(参见release和autorelease)。