URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 4823
[ Назад ]

Исходное сообщение
"Свободная память"

Отправлено sandy , 07-Ноя-05 18:33 
Имеется класс:

class Class {
std::vector<std::vector<char*> >* v;
/* */
};

В одной из функций класса есть следующее:
v=new std::vector<std::vector<char*> >(n, std::vector<char*>(m));
...
и дальше:
(*v)[n][m]=new char[SIZE];

Так вот, хочу спросить, нужно ли в деструкторе этого класса поубивать все, что созданно оператором new, или достаточно:
delete v;

Заранее благодарю.


Содержание

Сообщения в этом обсуждении
"Свободная память"
Отправлено Alexander S. Salieff , 07-Ноя-05 20:30 
>Имеется класс:
>
>class Class {
> std::vector<std::vector<char*> >* v;
> /* */
>};
>
>В одной из функций класса есть следующее:
>v=new std::vector<std::vector<char*> >(n, std::vector<char*>(m));
>...
>и дальше:
>(*v)[n][m]=new char[SIZE];
>
>Так вот, хочу спросить, нужно ли в деструкторе этого класса поубивать все,
>что созданно оператором new, или достаточно:
>delete v;
>
>Заранее благодарю.

Конечно нужно. При деструкции этих векторов освободится только память, выделенная под указатели. Выделенная вами память, на которую указывают эти указатели, сама по себе не освободится.
Тут проще не вдаваться в подробности, а руководствоваться правилом, что все, что явно аллоцировано (new, *alloc) должно быть явно освобождено (delete, free). Конечно существуют всякие авторегистративные структуры и смартпоинтеры, скрывающие от конечного программера освобождение памяти, но во первых, это явно не тот случай, а во вторых, ежели покопаться внутрях таких структур, то там тоже можно найти это самое явное освобождение.


"Свободная память"
Отправлено sandy , 08-Ноя-05 10:46 
>Конечно нужно. При деструкции этих векторов освободится только память, выделенная под указатели.
>Выделенная вами память, на которую указывают эти указатели, сама по себе
>не освободится.
>Тут проще не вдаваться в подробности, а руководствоваться правилом, что все, что
>явно аллоцировано (new, *alloc) должно быть явно освобождено (delete, free). Конечно
>существуют всякие авторегистративные структуры и смартпоинтеры, скрывающие от конечного программера освобождение
>памяти, но во первых, это явно не тот случай, а во
>вторых, ежели покопаться внутрях таких структур, то там тоже можно найти
>это самое явное освобождение.


Спасибо за исчерпывающий ответ. Может заодно подскажете, нужно ли явно вызывать деструктор


"Свободная память"
Отправлено Hordi , 08-Ноя-05 19:25 
Рекомендую почитать нормальную книгу! Вы спрашиваете базовые понятия - за этим нужно не на форум идти.

"Свободная память"
Отправлено hatta , 14-Ноя-05 18:43 
>Рекомендую почитать нормальную книгу! Вы спрашиваете базовые понятия - за этим нужно
>не на форум идти.

Рекомендую не раздражаться по пустякам))
Да, надо явным образом вызывать delete, тем более, что хуже от лишнего его вызова не станет.


"Свободная память"
Отправлено Alexander S. Salieff , 14-Ноя-05 20:12 
>>Рекомендую почитать нормальную книгу! Вы спрашиваете базовые понятия - за этим нужно
>>не на форум идти.
>
>Рекомендую не раздражаться по пустякам))
>Да, надо явным образом вызывать delete, тем более, что хуже от лишнего
>его вызова не станет.

Вот это ты явно погорячился. Современные glibc (при включенном MALLOC_CHECK_) ажно корки на "double free corruption" бросают, так как хуже не станет.
Ты сам подумай, у компилера есть конкретная реализация сохранения сегментных данных по аллоцированному указателю, эти данные используются при освобождении и потом за их сохранность никто не отвечает. Либо там появится мусор, либо наборот все сохранится, но при этом аллоцируется пересекающийся с освобожденным сегмент. И тут тебе твой лишний вызов такого наосвобождает, что мало не покажется.
Если в жизни не встречались подобные ситуации, это не значит, что их нету.


"Свободная память"
Отправлено hatta , 15-Ноя-05 16:57 
Нет ничего проще. Если по этому адресу был блок -- он удалится. Есть, правда, ничтожная вероятность того, что после удаления некоторого объекта точно на то же место был сконструирован другой, но мне кажется, это не актуально, если это, конечно, не система управления реактором))

"Свободная память"
Отправлено Alexander S. Salieff , 15-Ноя-05 17:11 
>Нет ничего проще. Если по этому адресу был блок -- он удалится.
>Есть, правда, ничтожная вероятность того, что после удаления некоторого объекта точно
>на то же место был сконструирован другой, но мне кажется, это
>не актуально, если это, конечно, не система управления реактором))

Во-первых, не такая уж и ничтожная. А во вторых все вот эти "не система управления реактором" наводят на грустные мысли и аллюзии на топик некоего "программера" который страдал от невозможности контролировать выходы за границы массива посредством Win32-SEH, другие методы ему были неведомы.
В субъекте программерской мысли софт должен быть абсолютно безглючным, никаких осознанных допущений на тему "авось прокатит". Объективный анализ крупного и сложного продукта и так выявит там кучу косяков, которые просто не пришли в голову программера.
Странный маскарад виртуализации выходит какой-то. Если у вас в руках через КЗ взорвется миксер, потому как кто-то не рассчитал толщину изолятора на авось "что таких больших скачков в сети не будет" - это производственное преступление. А если явно сказано и в POSIX-man'ах и в MSDN'е что при повторном освобождении поведение libc-аллокатора неопределено, но программер все одно делает double free corruption, софт падает, данные херятся (пусть и не на ядерном реакторе, а на кухне или в домашней бухгалиерии) - это пофиг, главное чтоб не нашли. А когда потом таких сажают, они искренне удивляются - "за что? Я простой программист, и никаких специализированных актов не подписывал и т.д."
Жуть, меня просто такие темы не радуют офигенно, или ты умеешь использовать инструмент производства, или носа не показывай с испытательного полигона, пока не научишься.


"Свободная память"
Отправлено Hordi , 15-Ноя-05 22:23 
To hatta: Вы хоть понимаете что советуете? Бред полный! Если был блок-удалится... Вероятность какая-то...

Согласно стандарта - повторный вызов delete над недействительным не NULL указателем приведет к НЕОПРЕДЕЛЕННОМУ поведению! Какая может быть неоднозначность?


"Свободная память"
Отправлено Hatta , 25-Ноя-05 23:49 
>To hatta: Вы хоть понимаете что советуете? Бред полный! Если был блок-удалится...
>Вероятность какая-то...
>
>Согласно стандарта - повторный вызов delete над недействительным не NULL указателем приведет
>к НЕОПРЕДЕЛЕННОМУ поведению! Какая может быть неоднозначность?

С вашим бы запалом сибирь покорять. Я действительно думаю, что ничего страшного не случится, если случайно дважды удалить блок. Если пишется серьезная программа, то эту ошибку скорее всего отловят тесты, исправить ее будет не так уж и сложно, модифицировав поведение оператора delete. И все.


"Свободная память"
Отправлено DeadMustdie , 27-Ноя-05 14:19 
>исправить ее будет не так уж и сложно, модифицировав поведение
>оператора delete. И все.

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


"Свободная память"
Отправлено Hordi , 28-Ноя-05 12:30 
>Я действительно думаю, что ничего страшного
>не случится, если случайно дважды удалить блок. Если пишется серьезная
А Вы, случайно, в "Русскую рулетку" не играете?

"Свободная память"
Отправлено vvvua , 30-Ноя-05 13:31 
В линухах вылетает прога при повторном delete. Либы и компилер последней свежести.

Всегда делаю теперь

if(a!=NULL)
  delete a;

>To hatta: Вы хоть понимаете что советуете? Бред полный! Если был блок-удалится...
>Вероятность какая-то...
>
>Согласно стандарта - повторный вызов delete над недействительным не NULL указателем приведет
>к НЕОПРЕДЕЛЕННОМУ поведению! Какая может быть неоднозначность?



"Свободная память"
Отправлено Hordi , 30-Ноя-05 13:36 
>if(a!=NULL)
>  delete a;

Это лишнее. delete сам на NULL проверяет. Но delete переданный ему указатель не обнуляет, поэтому или обнуляйте сами или думайте что делаете.


"Свободная память"
Отправлено Hordi , 14-Ноя-05 22:44 
>Рекомендую не раздражаться по пустякам))
Да нет, и в мыслях не было... Действительно нужно до таких вещей дойти самостоятельно.