6

我只是好奇这段代码是否会造成多个内存泄漏,或者它是否会被正确清理。

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();
}

delete newNode;

所以显然代码没有做任何事情,但它确实帮助我解释了我的场景。我是否分配了 10 次内存,当我删除留下 9 个孤儿的指针时?或者我是否重复使用分配的相同空间并正确删除孤儿?提前致谢!

4

2 回答 2

7

是的,这是泄漏内存。当你这样做时:

newNode = new Node();

您正在重新定义指针以指向新分配的内存,实际上失去了对先前指向内存的寻址方式以将其删除。

因此,当您离开循环时,newNode指针指向最后分配的(第十个)内存/ Node。当您delete newNode仅删除该内存时。你不再有delete其他人的方式。

正如Zhi Wang指出的那样,您可以使用某种形式的智能指针(例如unique_ptrshared_ptr在 C++11 中)。这些智能指针基本上是围绕常规指针的包装器,它们具有防止这种泄漏的附加语义。如果您使用其中之一,内存/对象将在超出范围时自动释放(for在这种情况下,在循环的当前迭代结束时)。

但是,我认为这不会解决您在这种情况下的情况。delete我怀疑你一创建它们就想要10 个对象。相反,您可能希望将这些对象存储在像 a 这样的容器中,std::vector或者至少有一个指向每个已分配实例的指针数组。这样,您将拥有周围的对象(我相信这是您想要的,因为您正在构建它们)并且还有一种稍后删除它们的方法。

于 2013-03-14T03:39:00.027 回答
5

是的,您的代码泄漏了内存。您对行为的第一个猜测是正确的。这段代码

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();  // allocate memory 10 times in a loop...
}

delete newNode;            // ... but free the memory only once!

分配内存 10 次(循环new内的运算符for),但释放仅由其中一个对象(delete底部的运算符)使用的内存。自然,这会使其他 9 个对象成为孤立对象——它们消耗的内存仍然被分配,但您现在无法访问它来释放它。当然,这就是内存泄漏的定义。

相比之下,这段代码

Node *newNode;

for (int i = 0; i < 10; i++)
{
    newNode = new Node();    // allocate memory 10 times in a loop
    delete newNode;          // ... and free the memory each time
}

不会泄漏任何内存,因为delete每次调用new. 这是您必须牢记的大规则:如果您没有将每个调用new与相应的调用匹配到delete,您将有内存泄漏

或者,当您在 C++ 中工作时,也许更好的规则是从一开始就不要使用原始指针。C++ 标准库提供了几个很好的包装类,它们实现了指针的 RAII 惯用语,这确保了指向的对象被正确地销毁,因此它们消耗的内存被释放。在您最喜欢的 C++ 书籍Wikipedia上开始您的研究。

于 2013-03-14T03:47:09.523 回答