简体   繁体   English

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

[英]Why does one code produce a memory leak and the other doesn't?

Why does this code produce a memory leak? 为什么这段代码会产生内存泄漏? I'm a newbie and don't understand it. 我是新手,不明白。 The object gets assigned to the shared_ptr so it's still accessible or not? 该对象被分配给shared_ptr,所以它仍然可以访问? I need to create the new instance in another function so I can't think of another way to do that. 我需要在另一个函数中创建新实例,所以我想不出另一种方法。 Is there anything I need to fix? 有什么需要修理的吗?

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

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

Also what is the difference between the above mentioned code and 还有上面提到的代码和之间的区别

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

regarding memory leaks? 关于内存泄漏?

There is a subtle difference. 有一个微妙的区别。

Whenever the constructor of MyClass throws, new MyClass(); 每当MyClass的构造函数抛出时, new MyClass(); does not produce any memory leak since the storage allocated for MyClass is automatically freed by new when an exception is thrown . 不会产生任何内存泄漏,因为在抛出异常时,MyClass分配的存储会new自动释放 In the snippets displayed in your question, none of the forms lead to memory leak. 在您的问题中显示的代码段中,没有任何表单导致内存泄漏。

But, if one would expand the definition of getNewMyClassInstance() in such a way than an exception is thrown at scope exit, your first form does lead to memory leak: 但是,如果以这种方式扩展getNewMyClassInstance()的定义而不是在作用域出口处抛出异常,则第一个表单会导致内存泄漏:

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

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

With this form (a raw pointer returned by a function and then acquired by a smart pointer), there is a small gap where memory could be lost. 使用这种形式(由函数返回的原始指针然后由智能指针获取),存在可能丢失内存的小间隙。 Almost always this is not an issue, but it might be for you. 几乎总是这不是问题,但它可能适合你。

As an alternative, why won't you define: 作为替代方案,您为什么不定义:

std::shared_ptr<MyClass> MyClass::getNewMyClassInstance()
{
    return std::make_shared<MyClass>();
}

The point I suspect that someone is making is that by returning the shared pointer, you ensure that the pointer is always wrapped by a smart pointer. 我怀疑有人在做的是通过返回共享指针,确保指针始终由智能指针包装。 By returning a naked pointer; 通过返回一个裸指针; this guarantee is lost; 这种保证丢失了; and thus leaves it more open to accidental leaks; 从而使其对意外泄漏更加开放; ie

 { getNewMyClassInstance()->doStuff() }

will leak in one case; 将在一个案件中泄漏; but not in the other. 但不是在另一个。

However; 然而; the example usage you posted will not leak. 您发布的示例用法不会泄露。

Actually your code does not produce any memory leak. 实际上你的代码不会产生任何内存泄漏。 But to answer your second question: 但要回答你的第二个问题:

  • in the first form, it can produce a memory leak if you don't pay attention on the returned value of getNewMyClassInstance() . 在第一种形式中,如果不注意getNewMyClassInstance()的返回值,它可能会产生内存泄漏。 I mean you return a raw pointer then the caller may forget to free it correctly. 我的意思是你返回一个原始指针然后调用者可能忘记正确释放它。 You can return a shared pointer to have a better code. 您可以返回共享指针以获得更好的代码。
  • the first form is more like using a factory, which leads to more degree of freedom in the way instances are created. 第一种形式更像是使用工厂,这导致了实例创建方式的更大自由度。

Neither of these pieces of code creates a memory leak. 这些代码都没有造成内存泄漏。

You have nothing to "fix". 你没有“修复”的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM