将新值分配给变量时泄漏内存?

时间:2011-08-08 13:27:08

标签: c++ memory pointers new-operator memory-leaks

是的,我是那些正在学习来自Java的C ++的人之一,被自动垃圾收集器宠坏了。有一种特殊的情况,我想知道我是否在泄漏记忆。我们在C ++中考虑一下:

bool *test = new bool(false);
test = new bool(true);
delete test;

我在这里泄漏记忆吗?或者我应该在分配新值之前先拨打delete?像这样:

bool *test = new bool(false);
delete test;
test = new bool(true);
delete test;

我的直觉告诉我第一个是正确的,因为指针test指向内存中的同一地址,并为其变量分配新值,不会更改此地址。或new运算符在内存中分配不同的地址?任何人都可以给我一个线索,或者我是否一起弄错了?

7 个答案:

答案 0 :(得分:6)

是的,你正在泄漏,而c ++的方法是:

bool test = false;
test = true; 

// ta-da - no leak.

你可以做第二种方法 - 但是你可能会画很多皱眉......

答案 1 :(得分:5)

是的,确切地说,在覆盖地址之前,您必须delete。或者更好的是在堆栈上分配或使用智能指针。

答案 2 :(得分:1)

你确实被宠坏了。

问题是你没有区分地址和变量。


bool *test = new bool(false);
  • test
  • 的自动持续时间分配空间
  • 为bool分配具有动态持续时间的空间
  • false写入此空间
  • 将此空间的地址存储到test

test = new bool(true);
  • 为bool分配具有动态持续时间的空间
  • true写入此空间
  • 将此空间的地址存储到test(先前存储的地址被无情地丢弃,因为它不存储在其他任何地方,它指向的内存永远无法回收,这意味着您有泄漏)。

delete test;
  • 读取存储在test
  • 中的地址
  • 取消分配此地址的空间

  

我的直觉告诉我第一个是正确的,因为指针测试指向内存中的同一地址,并为其变量分配新值,不会更改此地址。或者new运算符是否在内存中分配了不同的地址?

在语义上,您应该考虑new总是将地址返回到内存中的new空间(显然是错误的,因为内存被重用)。这就是为什么每次拨打new时都需要通过delete进行一次调用来匹配。

因此,你的直觉是错误的,new不会创造“只是”一个变量。如果你来自Java,这可能确实令人震惊,你需要一个强大的教程来掌握编程的细节。

答案 3 :(得分:0)

是的,你正在泄漏记忆。对于每个new,应该有一个后续的delete。如果用新地址覆盖指针,则会失去将分配与delete配对的机会。

答案 4 :(得分:0)

是的,你的第一个例子实际上是泄漏内存。 new的每次调用必须与delete匹配(除非new失败)。

在C ++中,执行你想要做的事情的正常方法是简单地在本地声明bool:

bool b = truel
b = false;

但是,如果您因某种原因确实需要动态分配,那么有智能指针可以管理内存,因此您不必担心调用delete。您可以查看scoped_ptrunique_ptrshared_ptr

最后,C ++有一个很好的标准库,可以处理许多可能的容器和算法,防止你不得不重新发明它们,并使你不必在各种情况下处理动态分配。

如果你认真学习C ++,我会从SO C ++书籍清单中挑选出一本书,并从头开始学习,而不是试图将Java习语转换为C ++(它不会很好用)。

答案 5 :(得分:0)

bool是一个内置的数据类型。为什么你需要像这样分配内存?你可以轻松地在堆栈上分配

答案 6 :(得分:0)

是的,你是在第一种情况下泄漏记忆。第二种方式是正确的方法。在你的第一个案例......

第二次调用new时,第一次分配超出范围,但仍然存在。在Java中,这很好,因为GC会为你清理它。但是,在C ++中,原始的反对者没有这种方式。

每次调用new都必须在某个时候调用delete。此外,删除指针后,将其设置为null或0.这将防止您意外删除无效的内存。