#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 и только его.