是的,我是那些正在学习来自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
运算符在内存中分配不同的地址?任何人都可以给我一个线索,或者我是否一起弄错了?
答案 0 :(得分:6)
是的,你正在泄漏,而c ++的方法是:
bool test = false;
test = true;
// ta-da - no leak.
你可以做第二种方法 - 但是你可能会画很多皱眉......
答案 1 :(得分:5)
是的,确切地说,在覆盖地址之前,您必须delete
。或者更好的是在堆栈上分配或使用智能指针。
答案 2 :(得分:1)
你确实被宠坏了。
问题是你没有区分地址和变量。
bool *test = new bool(false);
test
false
写入此空间test
test = new bool(true);
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_ptr
,unique_ptr
和shared_ptr
。
最后,C ++有一个很好的标准库,可以处理许多可能的容器和算法,防止你不得不重新发明它们,并使你不必在各种情况下处理动态分配。
如果你认真学习C ++,我会从SO C ++书籍清单中挑选出一本书,并从头开始学习,而不是试图将Java习语转换为C ++(它不会很好用)。
答案 5 :(得分:0)
bool是一个内置的数据类型。为什么你需要像这样分配内存?你可以轻松地在堆栈上分配
答案 6 :(得分:0)
是的,你是在第一种情况下泄漏记忆。第二种方式是正确的方法。在你的第一个案例......
第二次调用new时,第一次分配超出范围,但仍然存在。在Java中,这很好,因为GC会为你清理它。但是,在C ++中,原始的反对者没有这种方式。
每次调用new都必须在某个时候调用delete。此外,删除指针后,将其设置为null或0.这将防止您意外删除无效的内存。