Вызывается деструктор, когда объект выходит из области видимости?

Например:

int main() { Foo *leedle = new Foo(); return 0; } class Foo { private: somePointer* bar; public: Foo(); ~Foo(); }; Foo::~Foo() { delete bar; } 

Будет ли деструктор неявным образом вызван компилятором или будет ли утечка памяти?

Я новичок в динамической памяти, поэтому, если это не подходит для использования, я сожалею.

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

    Заголовок вопроса спрашивает, вызывается ли деструктор, когда переменная выходит за frameworks. Предположительно, вы хотели спросить:

    будет ли деструктор Foo вызываться в конце main ()?

    Учитывая предоставленный вами код, ответ на этот вопрос отсутствует, поскольку объект Foo имеет динамическую продолжительность хранения, как мы вскоре увидим.

    Обратите внимание, что такое автоматическая переменная:

     Foo* leedle = new Foo(); 

    Здесь leedle – это автоматическая переменная, которая будет уничтожена. leedle – это просто указатель. То, что указывает leedle , не имеет автоматической продолжительности хранения и не будет уничтожено. Итак, если вы это сделаете:

     void DoIt() { Foo* leedle = new leedle; } 

    Вы просачиваете память, выделенную new leedle .


    Вы должны delete все, что было выделено new :

     void DoIt() { Foo* leedle = new leedle; delete leedle; } 

    Это делается намного проще и надежнее, используя интеллектуальные указатели. В C ++ 03:

     void DoIt() { std::auto_ptr  leedle (new Foo); } 

    Или в C ++ 11:

     void DoIt() { std::unique_ptr  leedle = std::make_unique  (); } 

    Умные указатели используются как автоматические переменные, как указано выше, и когда они выходят за пределы области действия и уничтожаются, они автоматически (в деструкторе) delete объект, на который указывают. Поэтому в обоих случаях выше отсутствует утечка памяти.


    Попробуем прояснить здесь немного языка. В C ++ переменные имеют продолжительность хранения. В C ++ 03 существует 3 продолжительности хранения:

    1: автоматический : переменная с автоматической продолжительностью хранения будет уничтожена в конце блока кода.

    Рассматривать:

     void Foo() { bool b = true; { int n = 42; } // LINE 1 double d = 3.14; } // LINE 2 

    В этом примере все переменные имеют автоматическую продолжительность хранения. Оба b и d будут уничтожены на LINE 2. n будет уничтожено на LINE 1.

    2: static : переменная со статической продолжительностью хранения будет выделена до начала программы и уничтожена, когда программа закончится.

    3: dynamic : переменная с динамической продолжительностью хранения будет выделена при ее распределении с использованием функций распределения динамической памяти (например, new ) и будет уничтожена при ее уничтожении с использованием функций распределения динамической памяти (например, delete ).

    В моем первоначальном примере выше:

     void DoIt() { Foo* leedle = new leedle; } 

    leedle – переменная с автоматической продолжительностью хранения и будет уничтожена в концевой скобе. То, что указывает leedle имеет динамическую продолжительность хранения и не разрушается в коде выше. Вы должны вызвать delete чтобы освободить его.

    C ++ 11 также добавляет четвертую продолжительность хранения:

    4: thread : переменные с продолжительностью хранения streamа выделяются, когда stream начинается и освобождается, когда stream заканчивается.

    Да, если объект выходит из области видимости, деструктор получает вызов. НО Нет, деструктор не будет вызываться в этом случае, потому что у вас есть только указатель в области видимости, этот указатель не имеет конкретного деструктора, поэтому косвенный вызов для деструктора Foo не будет.

    Этот пример – область приложения интеллектуальных указателей, таких как std::unique_ptr и std::shared_ptr . Это фактические classы, которые, в отличие от необработанных указателей, имеют деструктор (условно), вызывающий delete на объект, указывающий на объект.

    Btw, деструктор удаления Foo удаляет bar , bar никогда не был инициализирован и не привязан к адресу, который указывает на фактический объект, поэтому вызов delete даст неопределенное поведение, вероятно, сбой.

    действительно была бы утечка памяти. Деструктор для объекта, выходящего из области видимости (Foo *), вызывается, но одно для объекта с указателем (выделенный вами Foo) не работает.

    С технической точки зрения, поскольку вы находитесь в основном, это не утечка памяти, поскольку вы до этого, когда приложение не завершено, вы можете получить доступ к каждой выделенной переменной. В этом отношении я цитирую Александреску (из Modern C ++, главу о одиночных играх)

    Утечки памяти появляются, когда вы распределяете накопленные данные и теряете все ссылки на нее. Здесь не так: ничего не накапливается, и мы сохраняем информацию о выделенной памяти до конца приложения. Кроме того, все современные

    Конечно, это не означает, что вы не должны называть delete , так как это будет крайне плохая (и опасная) практика.

    Прежде всего обратите внимание, что код не будет компилироваться; new возвращает указатель на объект, выделенный в куче. Тебе нужно:

     int main() { Foo *leedle = new Foo(); return 0; } 

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

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

    Interesting Posts

    Недопустимое сообщение подписи GoogleSignatureVerifier (google play services 9.0.0)

    Как анализировать даты в нескольких форматах с помощью SimpleDateFormat

    Как жесткий диск с жестким диском MBR превосходит 1,81 емкости TiB?

    R для установки рабочего каталога в исходное местоположение файла в Rstudio

    Как добавить локальную зависимость .jar-файла для файла build.gradle?

    Индексирование через точку монтирования в окнах

    Как я могу подключить Pidgin с помощью Facebook-чата (XMPP)?

    Ошибка MediaRecorder: -38

    Как получить текущий момент в формате ISO 8601 с датой, часом и минутой?

    Как я могу использовать средство просмотра событий для подтверждения времени входа в систему, отфильтрованного пользователем?

    Отключение Google Chrome Загрузка автоматической нумерации для существующих файлов

    Как установить Mac OS X 10.6 Snow Leopard в VMWare?

    Как восстановить потерянные / недоступные данные с моего устройства хранения?

    Объект Java BufferedWriter с utf-8

    как получить координаты щелчка мыши за пределами моего windows в Java

    Давайте будем гением компьютера.