在呼叫者或被呼叫者中释放内存?

Rah*_*hul 4 c++ memory-leaks memory-management

函数(Say"fun()")分配内存并将指针返回到已分配的内存.我应该如何确保释放此内存.我无法在函数"fun()"中立即释放它,因为它返回给调用者.如果fun()是图书馆的一部分怎么办?释放记忆是谁的责任.在fopen()的情况下,内存由fclose()释放.但在我的情况下,反复调用"fun()".所以我不能等到最后释放内存.

Fre*_*Foo 5

以下是在OP承认使用C++之前发布的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);
}
Run Code Online (Sandbox Code Playgroud)

在foolib 1.0中,foo_destroy只是

void foo_destroy(Foo *p)
{
    free(p);
}
Run Code Online (Sandbox Code Playgroud)

但在2.0版本中,它可能已经发展到了

void foo_destroy(Foo *p)
{
    fclose(p->logfile);
    free(p);
}
Run Code Online (Sandbox Code Playgroud)

此样式与不透明指针设计模式一致.它还为您提供了更换的自由,malloc并且free可以随时使用特殊用途的内存分配器(如池分配器),而无需更改任何客户端代码.


Sco*_*ham 5

如果它是C++,则不要将原始指针返回到内存,而是返回智能指针.

例如:

std::shared_ptr<TypePointedTo> data = fun();
Run Code Online (Sandbox Code Playgroud)

这样,当shared_ptr破坏时,它会自动为你释放内存.

或者,如果它是要返回的数组,请使用向量,这将自动为您释放内存:

std::vector<BYTE> data = fun();
Run Code Online (Sandbox Code Playgroud)

阅读优秀的评论,在很多场景中,std :: unique_ptr可能比std :: shared_ptr更好.

如果它是C ...看到其他答案!

  • 对于库来说,返回"shared_ptr"是非常糟糕的形式,因为这会对客户端施加一个可能不合适的策略.一旦对象由`shared_ptr`管理,它必须始终由`shared_ptr`管理.一个更好的解决方案是返回`std :: auto_ptr`; 通过调用`release()`,客户端代码可以恢复完全所有权并使用最合适的策略.如果最合适的策略是`shared_ptr` ...`shared_ptr`有一个带有`std :: auto_ptr`的构造函数. (3认同)
  • 如果**指向的对象由库和客户端代码共享,则返回`shared_ptr`**是一种非常好的形式.否则,`std :: unique_ptr`将是最合适的(或者确实是用于向后compat的`auto_ptr`). (3认同)