class Cls{
...//Переменные и методы класса.
};
int main(){
Cls *p = new Cls;
//что-то делаем с p.delete p; // Вот это зачем?
}
Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
Здравствуйте, gde11, Вы писали:
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
Не освобождай, в релиз версии скорее всего ничего страшного не произойдет. Но раз забьешь, два забьешь, а потом это в привычку войдет и польються memleak'и рекой.
Удачи!
/**
* у человека столько проблем, сколько он их себе создает
*/
Здравствуйте, gde11, Вы писали:
G>Вот программа:
G>
G>class Cls{
G>...//Переменные и методы класса.
G>};
G>int main(){
G> Cls *p = new Cls;
G> //что-то делаем с p.
G> delete p; // Вот это зачем?
G>}
G>
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
Во-первых, эта строка:
delete p;
не только освобождает память, но и вызывает деструктор класса Cls. Если он не тривиален (выполняет какие-нибудь
важные вещи типа освобождения дескрипторов ОС или закрытия файлов), то можно получить грабли.
А во-вторых, насчет освобождения памяти перед завершением программы — это филосовский вопрос. По-моему аллокатор
по умолчанию в SGI STL не освобождает память при работе с контейнерами.
Par-zzz wrote:
> Не освобождай, в релиз версии скорее всего ничего страшного не произойдет. > Но раз забьешь, два забьешь, а потом это в привычку войдет и польються > memleak'и рекой.
Жаль windows при закрытии процесса не пишет в лог о ликах. Быстро бы надоело
его вычищать. Заодно SGI STL allocator поправили бы
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Здравствуйте, gde11, Вы писали:
G>Вот программа:
G>
G>class Cls{
G>...//Переменные и методы класса.
G>};
G>int main(){
G> Cls *p = new Cls;
G> //что-то делаем с p.
G> delete p; // Вот это зачем?
G>}
G>
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
Можно положится на систему (если это хорошая система, конечно). В некоторых случаях так и делают, никакого криминала здесь нет. Однако полезно выработать привычку убирать за собой.
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить
все память, выделяемую программе. Или я что-то не понимаю?
Все дело в волшебных деструкторах. Без delete система память освободит, а деструктор не вызовет. Что, естественно, рушит многие технологии современного С++ программирования, типа RAII.
Здравствуйте, gde11, Вы писали:
G>Вот программа:
G>
G>class Cls{
G>...//Переменные и методы класса.
G>};
G>int main(){
G> Cls *p = new Cls;
G> //что-то делаем с p.
G> delete p; // Вот это зачем?
G>}
G>
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
Много причин.
Например, потому что так проще...
Зачем тебе в твой код дополнительная инфа о том,
что некий код используется прямо перед завершением работы и именно этот конкретный объект
можно и не удалять. А что если ты захочешь этот код использовать еще где и уже не
перед самых выходом из программы?
В целом проще следовать одной проверенной стратегии (выделил/попользовал/удалил),
чем несколькими:
— выделил/попользовал/удалил;
— выделил/попользовал/не удалил, потому что программа скоро завершится
— выделил/попользовал/не удалил, потому что памяти еще много...
Здравствуйте, gde11, Вы писали:
G>Вот программа:
G>
G>class Cls{
G>...//Переменные и методы класса.
G>};
G>int main(){
G> Cls *p = new Cls;
G> //что-то делаем с p.
G> delete p; // Вот это зачем?
G>}
G>
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
В таком слуае как этот и если говорить о Windows освобождать динамически участки памяти не обязательно. Операционная система сделает это сама, когда будет в систему возращать ресурсы.
Vamp wrote:
> Без delete система память освободит, а деструктор не вызовет.
Самое поразительное, что и при вызове delete может не вызваться деструктор!
Например:
#include <memory>
struct Pimpl; // определение в cpp файлеstruct P
{
std::auto_ptr<Pimpl> m_pimpl;
~P() {}
};
Кто не знает ответ, срочно в книжный магазин за хорошими книжками!
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Здравствуйте, alnsn, Вы писали:
A>Vamp wrote:
>> Без delete система память освободит, а деструктор не вызовет. A>Самое поразительное, что и при вызове delete может не вызваться деструктор! A>Например: A>
A>#include <memory>
A>struct Pimpl; // определение в cpp файле
A>struct P
A>{
A> std::auto_ptr<Pimpl> m_pimpl;
A> ~P() {}
A>};
A>
A>Кто не знает ответ, срочно в книжный магазин за хорошими книжками!
А какие, по вашему, хорошие?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Lorenzo_LAMAS wrote:
> "ComeauTest.c", line 6: warning: delete of pointer to incomplete class > delete p; > ^
Хороший компилятор поможет отложить покупку хороших книг
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
LaptevVV wrote:
> А какие, по вашему, хорошие?
Я честно говоря, хотел точную ссылку на книгу дать, но подзабыл, где это
было. Поэтому выразился абстрактно. Общий шаблон предположительно такой:
[More] (effective|exceptional) C++
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Vamp wrote:
> А g++ вообще отказался. Сказал, что еррор. > В любом случае, я так и не понял, о чем этот пример. http://www.boost.org/libs/utility/checked_delete.html
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Lorenzo_LAMAS wrote:
> А хороший ISO/IEC 14882 поможет отказаться от многих книг вообще.
По-хорошему, еще нужен список исправленных ошибок
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Здравствуйте, gde11, Вы писали:
G>Вот программа:
G>
G>class Cls{
G>...//Переменные и методы класса.
G>};
G>int main(){
G> Cls *p = new Cls;
G> //что-то делаем с p.
G> delete p; // Вот это зачем?
G>}
G>
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
Вот именно — вроде должна освободить память. А кто сказал, что это правда? Лучше delete пару раз где надо поставить.
Здравствуйте, _Stas, Вы писали:
_S>Здравствуйте, gde11, Вы писали:
G>>Вот программа:
G>>
G>>class Cls{
G>>...//Переменные и методы класса.
G>>};
G>>int main(){
G>> Cls *p = new Cls;
G>> //что-то делаем с p.
G>> delete p; // Вот это зачем?
G>>}
G>>
G>>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
_S>Вот именно — вроде должна освободить память. А кто сказал, что это правда?
Я, например.
_S>Лучше delete пару раз где надо поставить.
Интересно, интересно. Где это в рассматриваемом примере надо ставить delete два раза ???
Здравствуйте, alnsn, Вы писали:
A>Par-zzz wrote:
>> Не освобождай, в релиз версии скорее всего ничего страшного не произойдет. >> Но раз забьешь, два забьешь, а потом это в привычку войдет и польються >> memleak'и рекой. A>Жаль windows при закрытии процесса не пишет в лог о ликах. Быстро бы надоело A>его вычищать. Заодно SGI STL allocator поправили бы A>-- A>Александр Насонов, A>Независимый консультант и разработчик ПО A>alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Очень подмывает послать вас в магазин за хорошими книжками. Организация хипа целиком и полностью делается в user-mode. Система отвечает только за управление памятью процесса на страничном уровне.
Поэтому делать лог ликов нужно не на уровне ядра, а на уровне приложения. И, надо заметить, VC, например, это умеет делать для стандартного C run-time хипа. Пользуйтесь на здоровье.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, _Stas, Вы писали:
_S>>Здравствуйте, gde11, Вы писали:
G>>>Вот программа:
Ш>Интересно, интересно. Где это в рассматриваемом примере надо ставить delete два раза ???
Я не этот пример имел ввиду, когда писал ответ. Пару раз где надо – значит, что надо ставить delete ВЕЗДЕ после использования динамической памяти. Я стараюсь придерживаться правила – сколько new, столько и delete. В этом конкретном примере надо только 1 delete. Хотя если вы пишите по VC.NET, то там производиться сборка мусора.
Здравствуйте, _Stas, Вы писали:
_S>Я не этот пример имел ввиду, когда писал ответ. Пару раз где надо – значит, что надо ставить delete ВЕЗДЕ после использования динамической памяти. Я стараюсь придерживаться правила – сколько new, столько и delete. В этом конкретном примере надо только 1 delete.
А я нет. У меня в програме вобще delete не найти. Ибо религия не позволяет им пользоваться. У меня этим смартпоинтеры занимаются. _S>Хотя если вы пишите по VC.NET, то там производиться сборка мусора.
Не правда. Даже при включение managed extensions не все объекты подвержены сборке мусора. А без них этого понятия вобще нет.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, _Stas, Вы писали:
Ш>>Интересно, интересно. Где это в рассматриваемом примере надо ставить delete два раза ??? _S>Я не этот пример имел ввиду, когда писал ответ. Пару раз где надо – значит, что надо ставить delete ВЕЗДЕ после использования динамической памяти. Я стараюсь придерживаться правила – сколько new, столько и delete. В этом конкретном примере надо только 1 delete. Хотя если вы пишите по VC.NET, то там производиться сборка мусора.
А что ты будешь делать в этом случае:
void main()
{
char *data;
data = new char[10];
if (func1() == false)
{
delete[] data;
return;
}
if (func2() == false)
{
delete[] data;
return;
}
delete[] data;
}
На один new приходится 3 delete. Нестыковочка получилась. Твою концепцию надо пересматривать.
Шахтер wrote:
> Очень подмывает послать вас в магазин за хорошими книжками. Организация > хипа целиком и полностью делается в user-mode. Система отвечает только за > управление памятью процесса на страничном уровне. Поэтому делать лог ликов > нужно не на уровне ядра, а на уровне приложения. И, надо заметить, VC, > например, это умеет делать для стандартного C run-time хипа. Пользуйтесь > на здоровье.
Да я же это не серьезно. Забыл только смайл поставить
А вообще, есть системы на которых user-mode и kernel-mode неотделимы. Есть
даже такие, в которых в твое приложение встраивается операционка при
сборке.
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Здравствуйте, ArtDenis, Вы писали:
AD>Здравствуйте, _Stas, Вы писали:
Ш>>>Интересно, интересно. Где это в рассматриваемом примере надо ставить delete два раза ??? _S>>Я не этот пример имел ввиду, когда писал ответ. Пару раз где надо – значит, что надо ставить delete ВЕЗДЕ после использования динамической памяти. Я стараюсь придерживаться правила – сколько new, столько и delete. В этом конкретном примере надо только 1 delete. Хотя если вы пишите по VC.NET, то там производиться сборка мусора.
AD>А что ты будешь делать в этом случае: AD>
Самое интересное, что возможно через delete не только память освобождается...
... << RSDN@Home 1.1 beta 1 >>
Re: Зачем освобождать память через delete?
От:
Аноним
Дата:
13.02.04 14:25
Оценка:
Здравствуйте, gde11, Вы писали:
G>Вот программа:
G>
G>class Cls{
G>...//Переменные и методы класса.
G>};
G>int main(){
G> Cls *p = new Cls;
G> //что-то делаем с p.
G> delete p; // Вот это зачем?
G>}
G>
G>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
Для windows понятно, но
Попутно вопрос в разных версиях UNIX пямять освобождается или нет
A>Да я же это не серьезно. Забыл только смайл поставить A>А вообще, есть системы на которых user-mode и kernel-mode неотделимы. Есть A>даже такие, в которых в твое приложение встраивается операционка при A>сборке. A>-- A>Александр Насонов, A>Независимый консультант и разработчик ПО A>alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)
Здравствуйте, jazzer, Вы писали:
AD>>На один new приходится 3 delete. Нестыковочка получилась. Твою концепцию надо пересматривать.
J>автопойнтеры юзать
А как быть сишникам? У них пулемёту (я хотел сказать автозамёту) нету
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, gde11, Вы писали:
G>>Вот программа:
G>>
G>>class Cls{
G>>...//Переменные и методы класса.
G>>};
G>>int main(){
G>> Cls *p = new Cls;
G>> //что-то делаем с p.
G>> delete p; // Вот это зачем?
G>>}
G>>
G>>Я понимаю, что память надо освождать если она выделяется в цикле много раз и т. п. А надо ли это делать в приведенном примере? Ведь программа заканчивается и Windows вроде должна освободить все память, выделяемую программе. Или я что-то не понимаю?
А>Для windows понятно, но А>Попутно вопрос в разных версиях UNIX пямять освобождается или нет
попутно ответ — всегда освобождайте память и не майтесь подобными вопросами :)
наверняка найдется версия, которая не освобождает.
Например, ДОС :)
А>Для windows понятно, но А>Попутно вопрос в разных версиях UNIX пямять освобождается или нет
У меня такое ощущение, что мы имеем дело с избытком рефлексии. Память надо освобождать. Невзирая. Не зависимо от. Точка.
Андрей Галюзин wrote:
> И в итоге файл стал больше! Предлагаю его просто удалить
А я предложу добавить автоудаление при ошибке компиляции
$ g++ --autodelete-on-error test.cpp
Будет весело проблемы народа на форуме решать
--
Александр Насонов,
Независимый консультант и разработчик ПО
alnsn-mycop@yandex.ru (для более быстрого ответа удалите -мусор из адреса)