Что происходит с динамическим размещением объектов внутри объекта, который удаляется?

#c #pointers #memory-management #destructor

#c #указатели #управление памятью #деструктор

Вопрос:

Когда я использую delete ключевое слово для объекта, выполняется ли деструктор объектов? Что, если объект, который я удалил, содержит другие указатели, и я их не удаляю, это утечка памяти?

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

Комментарии:

1. Проблема не в delete ключевом слове, а в уничтожении любого объекта. Если вы покинете область, в которой ваш объект был выделен в куче, будет вызван деструктор, и ваша ссылка на указатель будет потеряна, точно так же, как если бы вы создали его с помощью new и уничтожили с помощью delete .

Ответ №1:

Когда я использую ключевое слово delete для объекта, выполняется ли деструктор объектов?

ДА.Для этого и предназначен деструктор.

Что, если объект, который я удалил, содержит другие указатели, и я их не удаляю, это утечка памяти?

ДА.Это один из наиболее распространенных источников утечек памяти.

Я не знаю, когда безопасно использовать delete, опасаясь удаления объекта, на который указывают откуда-то еще.

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

Ответ №2:

Когда я использую ключевое слово delete для объекта, выполняется ли деструктор объектов?

ДА

Что, если объект, который я удалил, содержит другие указатели, и я их не удаляю, это утечка памяти?

Да, если только у кого-то другого также нет указателя и этот кто-то другой отвечает за их удаление. У вас также могут возникнуть проблемы из-за двойного удаления. Если вы удалите данный вам указатель, но у кого-то другого есть указатель на эту память, то его указатель теперь указывает ни на что. Когда он использует этот указатель, его программа может аварийно завершиться.

Я не знаю, когда безопасно использовать delete, опасаясь удаления объекта, на который указывают откуда-то еще.

Вы не единственный. Важно установить протоколы и соглашения между частями вашего кода о том, кому что принадлежит. Что такое «создание» объектов. Что их «потребляет». Вы также можете захотеть использовать такие инструменты, как boost:: shared_ptr и boost::weak_ptr, чтобы разрешить подсчет ссылок.

Ответ №3:

Это утечка памяти. Это очень распространенная проблема. Когда вы удаляете объект, для которого вы использовали new для выделения памяти, он вызовет деструктор этих объектов. Деструктор — это то место, где вы должны предоставить реализацию для очистки (удаления) всей памяти, которую вы, возможно, выделили в течение срока службы этого объекта.

Ответ №4:

Если вы используете new, вы должны использовать delete. Это приведет к вызову деструктора экземпляра. Если этот экземпляр создает какие-либо объекты в своем конструкторе (или более поздней версии), он должен удалить их в своем деструкторе.

Кроме того, если вы создаете новые массивы (новый символ [20] и т.д.), Вы должны использовать ‘delete []’ при удалении, иначе поведение не определено.

Вы можете избежать многих проблем, используя std:: tr1::shared_ptr или boost::shared_ptr, которые будут выполнять подсчет ссылок и выполнять удаления за вас, то есть вместо:

 Foo *pFoo = new Foo;
  

делать

 std::tr1::shared_ptr<Foo> pFoo(new Foo);
  

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

Ответ №5:

Да, это утечка. Посмотрите, может ли часто задаваемые вопросы по управлению хранилищами помочь вам лучше понять.

Ответ №6:

Когда вы вызываете delete someObect; происходит что-то вроде этого:

 if(someObect != NULL)
{
someObect->~ClassName();// you did ClassName someObect = new ClassName(); 
operator delete(someObect);
}
  

И оператор delete, насколько я понимаю, делают то же самое, что и free — просто освобождают (освобождают) память. Но помните, что если вы использовали new, вы не можете использовать free, вы должны использовать delete и только его.