释放调用方或被调用方的内存
Freeing memory in caller or callee?
函数(例如"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)。
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 为什么调用堆栈数组会导致内存泄漏
- 调用析构函数以释放动态分配的内存
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 指向数组unique_ptr在调用 release() 后会自动释放动态内存,这是真的吗?
- 内联asm编译器屏障(内存阻塞器)是算作外部函数,还是算作静态函数调用
- 调用std::函数成员时内存损坏
- 对外部函数的调用是否强制从内存加载
- C++ 在不释放内存的情况下调用析构函数
- 如果我提前将参数声明为变量而不是将它们内联写入函数调用,那有什么区别(在内存方面)?
- ActiveMQ使用者的内存使用量在onMessage调用后不断增加
- 为什么创建进程 API 调用会导致内存访问冲突?
- 分配内存并在回调时调用C++的 Rust 函数崩溃
- 从 JNI 调用的 DLL 从哪里获取其内存以进行分配,例如 Malloc
- 在使用新操作员和C 中的结构的调用构造函数时,获得内存损坏(Malloc)
- 调用 shmdt() 后无法删除共享内存段
- 正在调用内存中对象的虚拟函数