gpt4 book ai didi

C++ 指针和内存泄漏

转载 作者:搜寻专家 更新时间:2023-10-31 02:20:29 30 4
gpt4 key购买 nike

我想说明一件事:

class Something {};

void do_something(const Something *p_sth) {}

然后:

do_something(new Something());

应该会导致内存泄漏,因为当您调用 new 时,您也应该始终调用 delete,对吧?这是一个好的解决方案吗?

void do_something(const Something *p_sth)
{
delete p_sth;
}

还是使用引用 & 更好?我还发现智能指针可以解决这个问题,所以不需要delete(这似乎是件好事,但我以前从未使用过)。我只想知道最好的解决方案是什么,以避免内存泄漏。谢谢

*谢谢大家的回答。它帮助我清理了一些东西。我也对我发布的代码感到抱歉,因为它可能太笼统了。

最佳答案

您关于假定指针所有权并删除对象的建议有问题。

这种行为在 C++ 中不是惯用的。程序员希望他们必须删除使用 new 分配的每个对象。如果您的函数的用户希望他们负责删除将其地址传递给函数的对象,那么您的解决方案就会分崩离析。此外,它会阻止将您的函数与调用结束后必须保持存在的对象一起使用:

Something* s = new s();
do_something(s);
s.foo() // oops, object was deleted, I can't use it anymore
delete s; // oops, double delete because I'm for some reason not responsible for deleting the object that I allocated

您的解决方案还可以防止在函数中使用自动和静态分配的对象。

Something s;
do_something(&s); //oops, do_something assumes that object is dynamically allocated

所有这些注意事项都必须记录给函数的用户。

在函数内部没有删除的原始指针没有这些问题。管理调用者的内存真的不应该是你的功能的责任。这样做会破坏单一责任原则。当您不想想要转让或共享所有权时,原始指针参数没有任何问题。如果您确实想暗示所有权发生变化,请使用专为此设计的智能指针。

智能指针不存在上述一些问题,但它们仍然会阻止使用自动和静态对象的功能。

在许多情况下,引用参数是理想的。它告诉调用者他们仍然对该对象负责。作为奖励,不需要 addressof 运算符允许稍微更好的语法。当然,调用者可能仍然会忘记管理他们的内存,但正如我所指出的,这不应该是你的责任。

引用有一个潜在的缺点。它们不能为空。如果您不需要 null,那么它实际上是一个优势。

哪种解决方案是理想的,取决于您的需要。以下并非适用于所有极端情况,但适用于大多数常见情况:

  • 如果要修改对象,则传递一个引用。
    • 除非你需要 null,在这种情况下使用指针
  • 如果你只是想读取对象,那么
    • 如果对象是可复制的、小的(大小小于或等于 word)、不包含指向动态对象的指针且不是多态的,则按值传递
    • 否则,或者如果您因为正在编写模板而不知道这些事情,请传递一个 const 引用
    • 除非你需要 null,在这种情况下使用指针
  • 如果你想转移所有权,那么使用unique_ptr
  • 如果您希望共享该所有权,请使用 shared_ptr

关于C++ 指针和内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32653090/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com