当我删除一个对象时,删除中引用的对象是否也被删除?
我有一个主要对象。它包含许多包含其他对象的数组。我想知道,当我删除主对象时,所有内存都会被释放(主对象和数组以及数组的对象(元素))吗?例如:
Fruit^ my_fruit = gcnew Fruit;
Apple^ first_apple = gcnew Apple;
Apple^ second_apple = gcnew Apple;
my_fruit->AppleList->Add(first_apple);
my_fruit->AppleList->Add(second_apple);
// some operations
delete my_fruit; // **is it enough to avoid memory leak, is it necessary to delete first and second apple objects?**
I have a main object. It holds a lot of arrays holding other objects. I wonder, when I delete the main object, will all the memory be released( main objects and the arrays and the objects(elements) of arrays )? For example:
Fruit^ my_fruit = gcnew Fruit;
Apple^ first_apple = gcnew Apple;
Apple^ second_apple = gcnew Apple;
my_fruit->AppleList->Add(first_apple);
my_fruit->AppleList->Add(second_apple);
// some operations
delete my_fruit; // **is it enough to avoid memory leak, is it necessary to delete first and second apple objects?**
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
由于您的 Fruit 和 Apple 对象是由 gcnew 实例化的,并且您的列表也是托管类型,因此您不需要对fruit 对象调用delete;垃圾收集器会处理它。
另一方面,如果 Fruit 对象中的列表是非托管类型,那么您将需要显式内存释放代码来释放列表,因为垃圾收集器不知道或不关心为该列表分配的内存。
最佳实践是为 Fruit 类定义一个析构函数,并将删除列表代码放入其中。对 Fruit 的删除调用将自动调用析构函数
http: //msdn.microsoft.com/en-us/library/248aa748(v=vs.80).aspx
(在 Matt 修正后编辑)
Since your Fruit and Apple objects are instantiated by gcnew, and your list is managed type as well, you won't need to call delete on the fruit object; the garbage collector will take care of it.
If on the other hand, say the list in the Fruit object was unmanaged type, then yes you would need explicit memory deallocation code to free the list since the garbage collector doesn't know or care about the memory allocated for that list.
The best practice would be to define a destructor for the Fruit class, and put the delete list code in there. The delete call to Fruit will automatically call the destructor
http://msdn.microsoft.com/en-us/library/248aa748(v=vs.80).aspx
(edited after Matt's correction)
删除调用不会释放内存。使用 gcnew 分配的内存将由垃圾收集器释放(而不是通过调用删除)。调用delete将调用析构函数(类似于C#中的Dispose)。请参阅以下内容:
http://bytes.com/topic/net/answers/735989-gcnew
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/19e35d8c-94c2-4ea0-8e27-8e5cb94e898e/
http://msdn.microsoft.com/en-us/库/ms177197(VS.80).aspx
The delete call will not release the memory. Memory allocated with gcnew will be freed by the garbage collector (not by your call to delete). Calling delete will call the destructor (which is analogous to Dispose in C#). See the following:
http://bytes.com/topic/net/answers/735989-gcnew
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/19e35d8c-94c2-4ea0-8e27-8e5cb94e898e/
http://msdn.microsoft.com/en-us/library/ms177197(VS.80).aspx
你没有内存泄漏。对于托管类型,内存由垃圾收集器释放(正如 Matt 和 sp1ky 已经声明的那样)。
delete
关键字用于处置对象。在列表上使用
delete
不会释放该列表中包含的任何对象。但是,您不是在列表上使用它,而是在父对象上使用它。所以这取决于父对象是否被写入自动处置其子对象。You do not have a memory leak. With managed types, memory is freed by the garbage collector (as Matt and sp1ky have already stated). The
delete
keyword is used to dispose the object.Using
delete
on a list will not dispose any objects contained inside that list. However, you aren't using it on the list, but on the parent object. So it depends on whether the parent object is written to automatically dispose its children.除了非常不寻常的程序之外,垃圾收集将“经常”发生,因此无需手动释放对象。您可能遇到的唯一问题是,如果您保留对大对象的引用的时间超过了您需要的时间。
例如,如果您在同一函数中加载和处理两个巨大的集合,并将它们存储在两个不同的变量中,则在处理第二个集合时,保存第一个集合的变量仍然有效。如果您实际上不再需要第一次收集,则垃圾收集器可能不会注意到,直到您从函数返回,然后两个收集都超出范围。如果两个集合不同时装入内存,那么这可能还不够快。
解决这个问题你可以做的就是尝试将你的代码分解成更小的单元,这样你就不会保留对事物的引用比你需要的时间更长的时间。有时,您无法在不破坏代码逻辑结构的情况下做到这一点,但请记住,您始终可以分配给变量,以便它不再保留对大对象的引用,然后该对象就有资格进行垃圾收集。
这有点像手动释放对象,只不过垃圾收集器会为您处理从该对象引用的任何其他内容,并且即使您无法确定其他地方是否需要该对象,您也可以以相同的方式对其进行编码在节目中。如果您手动管理内存,您将被迫想出一些策略来传达该对象是否仍然需要,或者保留它“以防万一”(这将是内存泄漏,就好像程序的其他部分没有一样) 正在使用它,没有人会释放它)。通过 GC 为您解决这个问题,您只需删除引用,如果其他地方需要该对象,它将保留下来,如果不需要,它将很快被删除。
Except for quite unusual programs, garbage collection will happen "often enough" that there is no need to manually deallocate objects. The only problem you might have is if you are holding onto references to large objects longer than you need to.
e.g. If you load and process two huge collections in the same function, and you store them in two different variables, the variable holding the first collection will still be live when you process the second collection. If you don't actually need the first collection anymore, the garbage collector might not notice until you return from the function and then both collections go out of scope. That might not be soon enough if the two collections don't both fit into memory at the same time.
What you can do to address this is try to break up your code into smaller units, so that you don't hold on to references to things much longer than you need to. Sometimes you can't do that without destroying the logical structure of your code, but remember that you can always assign to a variable so that it no longer holds a reference to the large object, which will then be eligible for garbage collection.
This is a bit like manually deallocating the object, except that the garbage collector takes care of whatever else was referenced from that object for you, and you can code it the same way even if you can't be sure whether the object is needed elsewhere in the program. If you were managing the memory manually you would be forced to come up with some strategy for communicating whether the object is still needed, or keep it "just in case" (which would be a memory leak, as if no other part of the program is using it no one would ever free it). With the GC figuring that out for you, you just remove your reference and if the object is needed elsewhere it will stick around, and if not it will be removed some time soon.