Когда я удаляю объект, удаляются ли объекты, на которые есть ссылки внутри? - PullRequest
0 голосов
/ 07 февраля 2012

У меня есть главный объект. Он содержит множество массивов, содержащих другие объекты. Интересно, когда я удаляю главный объект, будет ли освобождена вся память (основные объекты и массивы и объекты (элементы) массивов)? Например:

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?**

Ответы [ 4 ]

0 голосов
/ 08 февраля 2012

За исключением довольно необычных программ, сборка мусора будет происходить "достаточно часто", так что нет необходимости вручную освобождать объекты. Единственная проблема, с которой вы можете столкнуться, заключается в том, что вы держите ссылки на большие объекты дольше, чем нужно.

например. Если вы загружаете и обрабатываете две огромные коллекции в одной и той же функции и сохраняете их в двух разных переменных, переменная, содержащая первую коллекцию, все еще будет работать, когда вы обработаете вторую коллекцию. Если вам больше не нужна первая коллекция, сборщик мусора может не заметить, пока вы не вернетесь из функции, и тогда обе коллекции выйдут из области видимости. Этого может быть недостаточно, если обе коллекции не помещаются в память одновременно.

Что вы можете сделать, чтобы решить эту проблему, так это попытаться разбить ваш код на более мелкие блоки, чтобы вы не держали ссылки на вещи гораздо дольше, чем нужно. Иногда вы не можете сделать это, не разрушив логическую структуру вашего кода, но помните, что вы всегда можете присвоить переменную, чтобы она больше не содержала ссылку на большой объект, который затем будет иметь право на сборку мусора.

Это немного похоже на ручное освобождение объекта, за исключением того, что сборщик мусора позаботится обо всем, на что ссылался этот объект для вас, и вы можете кодировать его таким же образом, даже если вы не уверены, является ли объект нужен в другом месте в программе. Если бы вы управляли памятью вручную, вам пришлось бы придумать какую-то стратегию для сообщения о том, нужен ли объект по-прежнему, или оставить его «на всякий случай» (что могло бы привести к утечке памяти, как будто никакой другой части программы). - это , используя его, никто никогда не освободит его). Когда GC выяснит это для вас, вы просто удалите свою ссылку, и если объект понадобится где-то еще, он останется, а если нет, он будет удален в ближайшее время.

0 голосов
/ 07 февраля 2012

вызов удаления не освободит память.Память, выделенная с помощью gcnew, будет освобождена сборщиком мусора (а не вашим призывом к удалению).Вызов delete вызовет деструктор (который аналогичен Dispose в C #).Смотрите следующее: 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

0 голосов
/ 08 февраля 2012

У вас нет утечки памяти.Для управляемых типов память освобождается сборщиком мусора (как уже указали Matt и sp1ky).Ключевое слово delete используется для удаления объекта.

Использование delete в списке не приведет к удалению объектов, содержащихся в этом списке.Однако вы используете его не в списке, а в родительском объекте.Так что это зависит от того, написан ли родительский объект для автоматической утилизации его потомков.

0 голосов
/ 07 февраля 2012

Поскольку ваши объекты Fruit и Apple создаются с помощью gcnew, а ваш список также является управляемым типом, вам не нужно вызывать delete для объекта fruit; об этом позаботится сборщик мусора.

Если, с другой стороны, скажем, что список в объекте Fruit был неуправляемого типа, то да, вам понадобится явный код освобождения памяти для освобождения списка, поскольку сборщик мусора не знает или не заботится о памяти, выделенной для этого списка .

Лучше всего определить деструктор для класса Fruit и поместить туда список удаления. Вызов удаления во Fruit автоматически вызовет деструктор

http://msdn.microsoft.com/en-us/library/248aa748(v=vs.80).aspx

(отредактировано после исправления Мэтта)

...