Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 释放呼叫者或被呼叫者中的内存?_C++_Memory Management_Memory Leaks - Fatal编程技术网

C++ 释放呼叫者或被呼叫者中的内存?

C++ 释放呼叫者或被呼叫者中的内存?,c++,memory-management,memory-leaks,C++,Memory Management,Memory Leaks,函数(比如“fun()”)分配内存并返回指向已分配内存的指针。 如何确保释放此内存。我无法在函数“fun()”中立即释放它,因为它将返回给调用方。 如果fun()是库的一部分呢?谁的责任就是释放记忆。 对于fopen(),内存由fclose()释放。但在我的例子中,“fun()”被反复调用。所以我不能等到最后才释放内存。C解决方案: 如果fun()是库的一部分呢 然后,您的库api应该记录调用者需要释放内存的事实。 您还应该为该库提供一个免费函数,并要求库的用户调用它来免费分配 编辑: C++解

函数(比如“fun()”)分配内存并返回指向已分配内存的指针。 如何确保释放此内存。我无法在函数“fun()”中立即释放它,因为它将返回给调用方。 如果fun()是库的一部分呢?谁的责任就是释放记忆。
对于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 with
fclose
)。如果你不能预测将来是否需要额外的清理,那么最好假设在某个时候需要。包装
免费
很便宜

将其视为一种对称形式:如果客户机从库中获取资源(对象),那么它最终负责将其交还给库进行处理:

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++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();