我只是好奇这段代码是否会造成多个内存泄漏,或者它是否会被正确清理。
Node *newNode;
for (int i = 0; i < 10; i++)
{
newNode = new Node();
}
delete newNode;
所以显然代码没有做任何事情,但它确实帮助我解释了我的场景。我是否分配了 10 次内存,当我删除留下 9 个孤儿的指针时?或者我是否重复使用分配的相同空间并正确删除孤儿?提前致谢!
是的,这是泄漏内存。当你这样做时:
newNode = new Node();
您正在重新定义指针以指向新分配的内存,实际上失去了对先前指向内存的寻址方式以将其删除。
因此,当您离开循环时,newNode
指针指向最后分配的(第十个)内存/ Node
。当您delete newNode
仅删除该内存时。你不再有delete
其他人的方式。
正如Zhi Wang指出的那样,您可以使用某种形式的智能指针(例如unique_ptr
,shared_ptr
在 C++11 中)。这些智能指针基本上是围绕常规指针的包装器,它们具有防止这种泄漏的附加语义。如果您使用其中之一,内存/对象将在超出范围时自动释放(for
在这种情况下,在循环的当前迭代结束时)。
但是,我认为这不会解决您在这种情况下的情况。delete
我怀疑你一创建它们就想要10 个对象。相反,您可能希望将这些对象存储在像 a 这样的容器中,std::vector
或者至少有一个指向每个已分配实例的指针数组。这样,您将拥有周围的对象(我相信这是您想要的,因为您正在构建它们)并且还有一种稍后删除它们的方法。
是的,您的代码泄漏了内存。您对行为的第一个猜测是正确的。这段代码
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上开始您的研究。