Действительно ли сборка "мусора" является автоматической в стандартном C++?

Значения по умолчанию параметра метода:

public void MyMethod1(string value1 = "test", int num1 = 10, double num2 = 12.2)
{
  //...
}

Также, возможно, анонимные типы возврата:

public var MyMethod2()
{
  // ..
}
14
задан Wim 8 November 2009 в 17:13
поделиться

8 ответов

Длинный ответ на этот вопрос состоит в том, что каждый раз, когда вызывается new , где-то так или иначе, должно вызываться delete или какая-то другая функция освобождения (зависит от распределителя памяти и т. д.)

Но вам не обязательно быть тем, кто предоставляет вызов delete :

  1. Для C ++ существует сборка мусора в виде ] Сборщик мусора Ханса-Бема . Вероятно, существуют и другие библиотеки сборки мусора.
  2. Вы можете использовать интеллектуальные указатели, которые используют RAII (и подсчет ссылок, если указатель разрешает совместный доступ), чтобы определить, когда следует удалить объект. Хорошей библиотекой интеллектуальных указателей является интеллектуальный указатель Boost . Интеллектуальные указатели в подавляющем большинстве случаев могут заменить необработанные указатели.
  3. Некоторые среды приложений, такие как Qt , строят деревья объектов, так что существует отношение родитель-потомок для объектов, выделенных в куче фреймворка. В результате все, что нужно, - это вызвать delete для объекта, и все его дочерние элементы также будут автоматически delete d.

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

Что касается .NET, да, выделение с использованием gcnew означает, что память отслеживается .NET, поэтому утечек нет. Однако другие ресурсы, такие как дескрипторы файлов и т. Д., Не управляются сборщиком мусора.

и все его потомки автоматически будут delete d.

Если вы не хотите использовать какие-либо из этих методов, для защиты от утечек памяти, вы можете попробовать использовать инструмент проверки памяти. Valgrind особенно хорош, хотя он работает только в Linux

Что касается .NET, да, выделение с использованием gcnew означает, что память отслеживается .NET, поэтому утечек нет. Однако другие ресурсы, такие как дескрипторы файлов и т. Д., Не управляются сборщиком мусора.

и все его дочерние элементы автоматически будут delete d.

Если вы не хотите использовать какие-либо из этих методов, для защиты от утечек памяти вы можете попробовать использовать инструмент проверки памяти. Valgrind особенно хорош, хотя он работает только в Linux

Что касается .NET, да, выделение с использованием gcnew означает, что память отслеживается .NET, поэтому утечек нет. Однако другие ресурсы, такие как дескрипторы файлов и т. Д., Не управляются сборщиком мусора.

выделение с использованием gcnew означает, что память отслеживается .NET, поэтому утечек нет. Однако другие ресурсы, такие как дескрипторы файлов и т. Д., Не управляются сборщиком мусора.

выделение с использованием gcnew означает, что память отслеживается .NET, поэтому утечек нет. Однако другие ресурсы, такие как дескрипторы файлов и т. Д., Не управляются сборщиком мусора.

19
ответ дан 1 December 2019 в 06:53
поделиться

Yes you are right, in standard C++ (In managed C++ or other variants it depends) you must use delete after each new. In C#, Java and other garbage-collected languages, this is not necessary (in fact most of them doesn't have an equivalent to the "delete" operator).

2
ответ дан 1 December 2019 в 06:53
поделиться

You can use C++ with .NET in two ways: managed or unmanaged. In managed mode, .NET's garbage collection will take care of freeing memory on your behalf; in unmanaged mode, you're close to C++'s normal/standard behavior, so you have to take charge of your memory yourself.

1
ответ дан 1 December 2019 в 06:53
поделиться

Correct you have to worry about garbage collection on C++.

And... there is no need to worry about garbage collection on .NET.

Only if you have such intensive and long scripts that you feel need the optimization do you need to focus on that.

Edit: Both asveikau and Pavel Minaev comments are great, thanks! I overgeneralized to pass the message.

0
ответ дан 1 December 2019 в 06:53
поделиться

"there is no garbage collection in C++."

Correct.

1
ответ дан 1 December 2019 в 06:53
поделиться

В идиоматическом высокоуровневом C ++ вы никогда не вызываете delete .

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

Первое, что следует отметить, это то, что в C ++ вы используете new гораздо реже , чем вы используете new в C #. Это связано с тем, что в C # вы используете new всякий раз, когда вы создаете экземпляр структуры, класса или массива, но в C ++ вы используете new только тогда, когда хотите управлять элементом данных. динамически. Большинство данных в C ++ не требуют динамического управления и поэтому могут быть созданы без использования new . [Другими словами, new имеет другое значение в C #, чем в C ++. В C ++ он конкретно указывает на динамическое распределение, а в C # он используется для любых конструкций.]

Во-вторых, каждый раз, когда вы вызываете new в C ++, возвращаемое значение должно передаваться непосредственно в ] умный указатель . Интеллектуальный указатель гарантирует, что delete будет автоматически вызван для вас в подходящее время.

Кстати, если вы не гуру, пишущий низкоуровневую библиотеку (или студент, изучающий, как это сделать ), вы никогда не должны вызывать new для выделения массива в C ++. Стандартная библиотека (а также Boost / TR1) предоставляет классы шаблонов, которые выделяют массивы и управляют ими за вас.

Таким образом, C ++ не использует сборщик мусора , но имеет свою собственную форму автоматического управления памятью . Между этими двумя подходами есть небольшие различия, но оба подхода автоматизируют освобождение памяти, тем самым устраняя большинство типов утечек памяти.

Авторитетная демонстрация этих концепций дана создателем C ++ Бьярном Страуструпом в ответ на вопрос: Как бороться с утечками памяти?

См. Также:

9
ответ дан 1 December 2019 в 06:53
поделиться

Ваше утверждение об операторе new совершенно верно ... но оно несколько упрощает семантику C ++.

В C ++ объекты можно создавать в стеке или в куче:

class Foo {};

int main() {
  Foo obj1;
  Foo* obj2 = new Foo();
  delete obj2;
}

В приведенном выше примере obj1 создается в стеке, а obj2 создается в куче (с new). Объекты, созданные в куче, не уничтожаются, пока для них явно не будет вызвано удаление. Однако объекты в стеке автоматически уничтожаются, когда они выходят за пределы области видимости (т.е. когда main () возвращает в этом примере).

Это позволяет использовать идиому «Получение ресурсов - это инициализация» (также известная как RAII) в C ++, что в значительной степени более мощный, чем базовая сборка мусора. Ресурсы, которые необходимо очистить (память кучи, сокеты, файлы, соединения с БД и т. Д.), Обычно помещаются в объекты на основе стека, деструкторы которых заботятся об очистке.

В отличие от этого, Java и C # не позволяют создавать объекты в стеке и не гарантируют, что сбор данных когда-либо произойдет или что финализаторы будут работать (я не специалист по C #, поэтому я могу быть немного там неправильно). Таким образом, хотя вы получаете бесплатное управление памятью кучи в Java / C #, вы фактически получите гораздо больше кода очистки ресурсов на этих языках, чем в C ++.

8
ответ дан 1 December 2019 в 06:53
поделиться

Автоматическая сборка мусора полезна, но вы все равно можете получить утечки памяти, как показывает этот вопрос:

Утечки памяти в C # WPF

Это уменьшено в .NET и Java, но это не значит, что он позволяет автоматически устранять плохое кодирование.

Итак, в C ++ вам нужно явно выпустить то, что вы запрашиваете, и я думаю, что иногда это лучше, поскольку вы знаете, что происходит. Я хочу, чтобы в .NET и Java сборщик мусора мало работал в режиме отладки, чтобы люди знали, что они делают.

1
ответ дан 1 December 2019 в 06:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: