C++ 释放呼叫者或被呼叫者中的内存?
函数(比如“fun()”)分配内存并返回指向已分配内存的指针。 如何确保释放此内存。我无法在函数“fun()”中立即释放它,因为它将返回给调用方。 如果fun()是库的一部分呢?谁的责任就是释放记忆。C++ 释放呼叫者或被呼叫者中的内存?,c++,memory-management,memory-leaks,C++,Memory Management,Memory Leaks,函数(比如“fun()”)分配内存并返回指向已分配内存的指针。 如何确保释放此内存。我无法在函数“fun()”中立即释放它,因为它将返回给调用方。 如果fun()是库的一部分呢?谁的责任就是释放记忆。 对于fopen(),内存由fclose()释放。但在我的例子中,“fun()”被反复调用。所以我不能等到最后才释放内存。C解决方案: 如果fun()是库的一部分呢 然后,您的库api应该记录调用者需要释放内存的事实。 您还应该为该库提供一个免费函数,并要求库的用户调用它来免费分配 编辑: C++解
对于fopen(),内存由fclose()释放。但在我的例子中,“fun()”被反复调用。所以我不能等到最后才释放内存。C解决方案: 如果fun()是库的一部分呢 然后,您的库api应该记录调用者需要释放内存的事实。
您还应该为该库提供一个免费函数,并要求库的用户调用它来免费分配 编辑: C++解决方案: <> P>既然你编辑说你正在使用C++,也许最好使用智能指针(<代码> STD::Tr1::SyrdyPtR/Cuth>)自动处理内存。p>
如果由于某种原因无法使用智能指针,那么使用
std::vector也是一个不错的选择。如果需要被调用方之外的内存,很明显,它负责释放内存,因为无法在被调用方中真正释放内存。它与new
和delete
相同-您只需记住释放内存即可。确保记录调用者负责内存管理的事实。您必须记录内存已分配,调用者负责释放内存。你不能自己释放它,因为你不知道打电话的人的意图。你会在使用前释放它
您可以提供一个cleanUp()方法来调用并刷新内存,但这仍然依赖于调用者,并且在应该调用它的时候增加了复杂性
唯一的真正选择是建立一个聪明的“引用计数”机制,如Objto-C(参见释放和自动删除)。
<强>下面是C的答案,在使用C++的OP之前发布。< /强>在该语言中,使用RAII和智能指针,如其他人推荐的。
如果函数返回已分配的内存,则调用方负责释放,这必须在函数的文档中说明
如果需要更多的清理,则由免费提供
,或者在库的未来版本中可能需要此类清理,那么您应该提供一个清理功能(如stdio
does withfclose
)。如果你不能预测将来是否需要额外的清理,那么最好假设在某个时候需要。包装免费
很便宜
将其视为一种对称形式:如果客户机从库中获取资源(对象),那么它最终负责将其交还给库进行处理:
void use_the_foo_library()
{
Foo *f = make_foo();
if (f == NULL)
ERROR();
foo_do_bar(f);
foo_do_baz(f);
foo_destroy(f);
}
在傻瓜ib 1.0中,foo_destroy
只是
void foo_destroy(Foo *p)
{
free(p);
}
但在2.0版中,它可能已经发展到
void foo_destroy(Foo *p)
{
fclose(p->logfile);
free(p);
}
这种风格与设计模式是一致的。它还提供了在任何时候用特殊内存分配器(例如,A)代替“代码”> MalOC < /COD>和<代码>免费>代码>,不必更改任何客户端代码。 < P>如果是C++,不要将原始指针返回到内存,而是返回智能指针。
例如:
std::shared_ptr data=fun();
这样,当共享_ptr破坏时,它会自动为您释放内存
或者,如果要返回的是数组,请使用向量,这将自动为您释放内存:
std::vector<BYTE> data = fun();
std::vector data=fun();
阅读这些优秀的评论,std::unique\u ptr在很多场景中都可能比std::shared\u ptr更好
如果是C。。。看看其他答案在C++中,你将返回一个智能指针,它明确地声明(并强制)所有权已经转移到调用方,并允许调用方选择如何处理它。它还提供异常安全,防止在异常(或只是早期函数返回)导致指向资源的唯一指针超出范围时发生内存泄漏
在C++03中,std::auto_ptr
是这里的最佳选择;在C++ 11中,这是不赞成的,而不是<代码> STD::UnQuyJPPT< /C> > < /P>这是C还是C++?谁搞乱了应该清除它!将这种逻辑应用于内存管理。@EdHeal:这句话很好,但它可以用两种方式来解释。是谁搞的乱七八糟,图书馆还是决定打电话到图书馆的程序?谢谢。为什么不将指针传递给函数(也就是制造混乱的人),然后该函数就可以填充内存。内存可以在堆上,也可以在堆栈上。谢谢!!好奇的是,我们在标准的c/c++库中有这样的说法吗?@Rahul:把它想象成fopen
和fclose
,fopen
导致分配一些资源(句柄等),而用户在使用完文件后必须显式调用fclose
来释放这些资源,您的情况唯一不同的是资源是动态内存。@不,不是真的,但请看Als答案。@AmigableClarkKant:这是我的答案,抱歉。我不理解您的评论。现在我又读了一遍,可能是我自己弄糊涂了。:-)我的意思是,在任何标准中都没有规定第三方库必须以这种或那种方式工作。你的答案是很好的建议。这是C的一个好答案,但是请注意,问题已经被改变为现在引用C++。@ MikeSeymour:谢谢你的提醒,没见过。不过,我一直在收集投票:)对于一个库来说,返回共享的\u ptr
是一种非常糟糕的形式,因为这可能会对客户端施加不适当的策略。对象由共享\u ptr
管理后,必须始终由共享\u ptr
管理。远赌
std::vector<BYTE> data = fun();