一个函数(Say“fun()”)分配内存并将指针返回给已分配的内存。 我应该如何确保释放此内存。我无法在函数“fun()”中立即释放它,因为它返回给调用者。 如果fun()是图书馆的一部分怎么办?释放记忆是谁的责任。 在fopen()的情况下,内存由fclose()释放。但在我的情况下,反复调用“fun()”。所以我不能等到最后释放记忆。
答案 0 :(得分:5)
以下是在OP承认使用C ++之前发布的C的答案。在该语言中,按照其他人的建议使用RAII和智能指针。
如果函数返回已分配的内存,则调用者负责释放,这必须在函数文档中说明。
如果需要更多清理,则由free
提供,或者在库的未来版本中可能需要进行此类清理,那么您应该提供清理功能(如stdio
与{{} 1}})进行解除分配。如果你无法预测将来是否有必要进行额外的清理,那么假设它在某个时刻是个好主意。包裹fclose
很便宜。
将其视为一种对称形式:如果客户端从库中获取资源(对象),那么它最终负责将其交还给库进行处理:
free
在foolib 1.0中,void use_the_foo_library()
{
Foo *f = make_foo();
if (f == NULL)
ERROR();
foo_do_bar(f);
foo_do_baz(f);
foo_destroy(f);
}
只是
foo_destroy
但在版本2.0中,它可能已经发展到
void foo_destroy(Foo *p)
{
free(p);
}
等。此样式与opaque pointer设计模式一致。它还使您可以随时使用特殊用途的内存分配器(例如pool allocator)替换void foo_destroy(Foo *p)
{
fclose(p->logfile);
free(p);
}
和malloc
,而无需更改任何客户端代码。
答案 1 :(得分:5)
如果它是C ++,则不要将原始指针返回到内存,而是返回智能指针。
例如:
std::shared_ptr<TypePointedTo> data = fun();
这样,当shared_ptr破坏时,它会自动为你释放内存。
或者,如果它是要返回的数组,请使用向量,这将自动为您释放内存:
std::vector<BYTE> data = fun();
阅读优秀的评论,std :: unique_ptr在许多场景中可能比std :: shared_ptr更好。
如果是C ...请看其他答案!
答案 2 :(得分:2)
C解决方案:
如果fun()是图书馆的一部分怎么办?
然后你的库api应该记录调用者释放内存需要的事实 您还应该为此提供免费功能,并要求库的用户调用它以释放分配。
编辑:
C ++解决方案:
由于您编辑过说您正在使用C ++,因此最好使用智能指针(std::tr1::shared_ptr
)为您自动处理内存。
如果因某些原因无法使用智能指针使用std::vector
也是一个不错的选择。
答案 3 :(得分:2)
在C ++中,您将返回一个智能指针,该指针清楚地指出(并强制执行)所有权已传输给调用者,并允许调用者选择如何处理它。它还提供异常安全性,如果异常(或只是早期函数返回)导致资源的唯一指针超出范围,则防止内存泄漏。
在C ++ 03中,std::auto_ptr
是最好的选择;在C ++ 11中,不赞成使用std::unique_ptr
。
答案 4 :(得分:0)
如果你需要在被叫者之外的内存,很明显它负责释放内存,因为你无法在被叫方中真正释放它。它与new
和delete
相同 - 你必须记住释放那个记忆。确保记录调用者负责内存管理的事实。
答案 5 :(得分:0)
您必须记录已分配内存并且调用者负责释放内存。你不能自己解放,因为你无法知道来电者的意图。在使用之前你会释放它。
你可以提供一个cleanUp()方法来调用并刷新内存,但是仍然依赖于调用者,你会在应该调用它时添加复杂性。
唯一真正的替代方案是建立一个聪明的“引用计数”机制,例如在Objective-C中(参见发布和自动释放)。