为什么一个代码会产生内存泄漏而另一个代码却没有?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么一个代码会产生内存泄漏而另一个代码却没有?相关的知识,希望对你有一定的参考价值。

为什么这段代码会产生内存泄漏?我是新手,不明白。该对象被分配给shared_ptr,所以它仍然可以访问?我需要在另一个函数中创建新实例,所以我想不出另一种方法。有什么需要修理的吗?

std::shared_ptr<MyClass>newItem(getNewMyClassInstance());

MyClass* MyClass::getNewMyClassInstance()
{
    return new MyClass();
}

还有上面提到的代码和之间的区别

std::shared_ptr<MyClass>newItem(new MyClass());

关于内存泄漏?

答案

有一个微妙的区别。

每当MyClass的构造函数抛出时,new MyClass();不会产生任何内存泄漏,因为为MyClass分配的存储空间是automatically freed by new when an exception is thrown。在您的问题中显示的代码段中,没有任何表单导致内存泄漏。

但是,如果以这种方式扩展getNewMyClassInstance()的定义而不是在范围退出时抛出异常,则第一个表单会导致内存泄漏:

MyClass* MyClass::getNewMyClassInstance()
{
    ThrowsWhenDestructed t;
    return new MyClass();
}

std::shared_ptr<MyClass>newItem(getNewMyClassInstance());
// MyClass pointer is not acquired, and lost to oblivion.

使用这种形式(由函数返回的原始指针然后由智能指针获取),存在可能丢失内存的小间隙。几乎总是这不是问题,但它可能适合你。

作为替代方案,您为什么不定义:

std::shared_ptr<MyClass> MyClass::getNewMyClassInstance()
{
    return std::make_shared<MyClass>();
}
另一答案

我怀疑有人在做的是通过返回共享指针,确保指针始终由智能指针包装。通过返回一个裸指针;这种保证丢失了;从而使其对意外泄漏更加开放;即

 { getNewMyClassInstance()->doStuff() }

将在一个案件中泄漏;但不是在另一个。

然而;您发布的示例用法不会泄露。

另一答案

实际上你的代码不会产生任何内存泄漏。但要回答你的第二个问题:

  • 在第一种形式中,如果你不注意getNewMyClassInstance()的返回值,它会产生内存泄漏。我的意思是你返回一个原始指针然后调用者可能忘记正确释放它。您可以返回共享指针以获得更好的代码。
  • 第一种形式更像是使用工厂,这导致了实例创建方式的更大自由度。
另一答案

这些代码都没有造成内存泄漏。

你没有“修复”的东西。

以上是关于为什么一个代码会产生内存泄漏而另一个代码却没有?的主要内容,如果未能解决你的问题,请参考以下文章

Python - 解决内存泄漏问题

如何防止java中的内存泄漏

为啥这会导致内存泄漏?

为啥在 swift 中创建字符串时会出现内存泄漏?

为啥lua语言中使用全局变量就会造成内存泄漏呢??

ios在画布上使用display:none绘制图像导致内存泄漏