Имеется класс: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;Заранее благодарю.
>Имеется класс:
>
>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). Конечно существуют всякие авторегистративные структуры и смартпоинтеры, скрывающие от конечного программера освобождение памяти, но во первых, это явно не тот случай, а во вторых, ежели покопаться внутрях таких структур, то там тоже можно найти это самое явное освобождение.
>Конечно нужно. При деструкции этих векторов освободится только память, выделенная под указатели.
>Выделенная вами память, на которую указывают эти указатели, сама по себе
>не освободится.
>Тут проще не вдаваться в подробности, а руководствоваться правилом, что все, что
>явно аллоцировано (new, *alloc) должно быть явно освобождено (delete, free). Конечно
>существуют всякие авторегистративные структуры и смартпоинтеры, скрывающие от конечного программера освобождение
>памяти, но во первых, это явно не тот случай, а во
>вторых, ежели покопаться внутрях таких структур, то там тоже можно найти
>это самое явное освобождение.
Спасибо за исчерпывающий ответ. Может заодно подскажете, нужно ли явно вызывать деструктор
Рекомендую почитать нормальную книгу! Вы спрашиваете базовые понятия - за этим нужно не на форум идти.
>Рекомендую почитать нормальную книгу! Вы спрашиваете базовые понятия - за этим нужно
>не на форум идти.Рекомендую не раздражаться по пустякам))
Да, надо явным образом вызывать delete, тем более, что хуже от лишнего его вызова не станет.
>>Рекомендую почитать нормальную книгу! Вы спрашиваете базовые понятия - за этим нужно
>>не на форум идти.
>
>Рекомендую не раздражаться по пустякам))
>Да, надо явным образом вызывать delete, тем более, что хуже от лишнего
>его вызова не станет.Вот это ты явно погорячился. Современные glibc (при включенном MALLOC_CHECK_) ажно корки на "double free corruption" бросают, так как хуже не станет.
Ты сам подумай, у компилера есть конкретная реализация сохранения сегментных данных по аллоцированному указателю, эти данные используются при освобождении и потом за их сохранность никто не отвечает. Либо там появится мусор, либо наборот все сохранится, но при этом аллоцируется пересекающийся с освобожденным сегмент. И тут тебе твой лишний вызов такого наосвобождает, что мало не покажется.
Если в жизни не встречались подобные ситуации, это не значит, что их нету.
Нет ничего проще. Если по этому адресу был блок -- он удалится. Есть, правда, ничтожная вероятность того, что после удаления некоторого объекта точно на то же место был сконструирован другой, но мне кажется, это не актуально, если это, конечно, не система управления реактором))
>Нет ничего проще. Если по этому адресу был блок -- он удалится.
>Есть, правда, ничтожная вероятность того, что после удаления некоторого объекта точно
>на то же место был сконструирован другой, но мне кажется, это
>не актуально, если это, конечно, не система управления реактором))Во-первых, не такая уж и ничтожная. А во вторых все вот эти "не система управления реактором" наводят на грустные мысли и аллюзии на топик некоего "программера" который страдал от невозможности контролировать выходы за границы массива посредством Win32-SEH, другие методы ему были неведомы.
В субъекте программерской мысли софт должен быть абсолютно безглючным, никаких осознанных допущений на тему "авось прокатит". Объективный анализ крупного и сложного продукта и так выявит там кучу косяков, которые просто не пришли в голову программера.
Странный маскарад виртуализации выходит какой-то. Если у вас в руках через КЗ взорвется миксер, потому как кто-то не рассчитал толщину изолятора на авось "что таких больших скачков в сети не будет" - это производственное преступление. А если явно сказано и в POSIX-man'ах и в MSDN'е что при повторном освобождении поведение libc-аллокатора неопределено, но программер все одно делает double free corruption, софт падает, данные херятся (пусть и не на ядерном реакторе, а на кухне или в домашней бухгалиерии) - это пофиг, главное чтоб не нашли. А когда потом таких сажают, они искренне удивляются - "за что? Я простой программист, и никаких специализированных актов не подписывал и т.д."
Жуть, меня просто такие темы не радуют офигенно, или ты умеешь использовать инструмент производства, или носа не показывай с испытательного полигона, пока не научишься.
To hatta: Вы хоть понимаете что советуете? Бред полный! Если был блок-удалится... Вероятность какая-то...Согласно стандарта - повторный вызов delete над недействительным не NULL указателем приведет к НЕОПРЕДЕЛЕННОМУ поведению! Какая может быть неоднозначность?
>To hatta: Вы хоть понимаете что советуете? Бред полный! Если был блок-удалится...
>Вероятность какая-то...
>
>Согласно стандарта - повторный вызов delete над недействительным не NULL указателем приведет
>к НЕОПРЕДЕЛЕННОМУ поведению! Какая может быть неоднозначность?С вашим бы запалом сибирь покорять. Я действительно думаю, что ничего страшного не случится, если случайно дважды удалить блок. Если пишется серьезная программа, то эту ошибку скорее всего отловят тесты, исправить ее будет не так уж и сложно, модифицировав поведение оператора delete. И все.
>исправить ее будет не так уж и сложно, модифицировав поведение
>оператора delete. И все.Да Вы, батенька, опасный маньяк. И никогда не писали на C++ программ сколько-нибудь существенного размера.
>Я действительно думаю, что ничего страшного
>не случится, если случайно дважды удалить блок. Если пишется серьезная
А Вы, случайно, в "Русскую рулетку" не играете?
В линухах вылетает прога при повторном delete. Либы и компилер последней свежести.Всегда делаю теперь
if(a!=NULL)
delete a;>To hatta: Вы хоть понимаете что советуете? Бред полный! Если был блок-удалится...
>Вероятность какая-то...
>
>Согласно стандарта - повторный вызов delete над недействительным не NULL указателем приведет
>к НЕОПРЕДЕЛЕННОМУ поведению! Какая может быть неоднозначность?
>if(a!=NULL)
> delete a;Это лишнее. delete сам на NULL проверяет. Но delete переданный ему указатель не обнуляет, поэтому или обнуляйте сами или думайте что делаете.
>Рекомендую не раздражаться по пустякам))
Да нет, и в мыслях не было... Действительно нужно до таких вещей дойти самостоятельно.