В данном случае нет никакого смысла обнулять, т.к. после деструктора уже ничего нет и последующее, ошибочное использование указателя уже будет невозможно
PK>>Насколько это pb = 0 может быть нужно и по какой причине? PK>>(Извините, если уже было, не нашел).
J>Это так народ пытается нейтрализовать двойной вызов деструктора
Ну до кучи ещё может быть попытка нейтрализовать использование уже невалидного указателя на A.
A * a = new A();
a->SomeMethod(); // method uses A::pbdelete a;
a->SomeMethod();
Re[2]: Обнуление указателей в деструкторе
От:
Аноним
Дата:
04.06.09 10:25
Оценка:
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Peter K., Вы писали:
PK>>Насколько это pb = 0 может быть нужно и по какой причине? B>Абсолютно излишнее действие.
Не излишнее, см пост выше. После того как память освободилась, она не обнуляется, и если у тебя остался указатель на кусок памяти, где раньше жил объект, то ты можешь достучатся до полей мертвого объекта (с непредсказуемыми последствиями в дальнейшем). А если обнулишь, то сразу будет АВ шка.
Здравствуйте, Peter K., Вы писали:
PK>Насколько это pb = 0 может быть нужно и по какой причине?
1) Перестраховка. Обращение к деструированному объекту — это уже UB, только характер может меняться.
Диагностировать обращение к неожиданно нулевому указателю легче, чем к невалидному указателю куда-то в середину кучи.
В крайнем случае, быстро поймаешь ошибку защиты памяти. В противном случае, проедешься с бензопилой по чужим данным.
2) Либо неудачный/бездумный рефакторинг.
Написали reset, а потом обнаружили, что он используется лишь в деструкторе. И скопировали туда.
Либо наоборот — собрались писать reset и забросили, так и не выделив из деструктора.
3) Либо это лишь часть кода. А на деле там всё громоздче:
В роли foo() могут быть обратные вызовы каких-то союзнических функций, работающих с этим объектом.
Например, у тебя облако взаимосвязанных объектов, и запускается лавина рекурсивного удаления их всех.
(На мой взгляд, лавины — это дыра в архитектуре, но на скорую руку, бывает, терпимо).
PK>Насколько это pb = 0 может быть нужно и по какой причине? PK>(Извините, если уже было, не нашел).
потому что кто нить потом может сделать например так:
class B;
class A {
B * pb;
public:
A() : pb(new B()) {}
~A()
{
delete pb;
pb = 0;
CleanupAll();
}
void CleanupAll()
{
....
pb->Cleanup();
...
}
};
Tсли будет обнуление pb срузу после delete — то написанный кем то потом код сразу свалится в B::Cleanup() при обращении к данным/vftbl pb; А без обнуления будет UB — то бишь может свалится, может не свалится, может свалится потом, может свалится потом у каждого десятого юзера etc
Здравствуйте, R.O. Prokopiev, Вы писали:
B>>Абсолютно излишнее действие.
ROP>Нифига подобного.
ROP>Действие очень даже нужное.
Просвяти, в каких это случаях оно такое нужное?
ROP>Деструктор можно вызывать явно:
С этим никто не спорил
А вот обращение к полям разрушенного объекта — UB.
3.8/5
...
If the object will be or was of a non-POD class type, the program has undefined behavior if:
— the pointer is used to access a non-static data member or call a non-static member function of the object
Здравствуйте, Bell, Вы писали:
ROP>>Действие очень даже нужное. B>Просвяти, в каких это случаях оно такое нужное?
Видел явный вызов деструктора в потрохах CArray
(еще в те времена когда не перешел на STL).
Глянул в VC8 — осталось.
Посмотрел в стандарт.
Признаться был не совсем прав.
Многократный вызов деструктора чреват UB.
12.4/14
Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the
destructor is invoked for an object whose lifetime has ended (3.8). [ Example: if the destructor for an automatic
object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily
invoke implicit destruction of the object, the behavior is undefined. ]
В принципе все уже сказано. Но все равно добавлю
Я, например, всегда так делаю, ибо AV отладить куда проще, особенно если мозги позволили добавить в рогу создание crash-dump'ов.
При наличие того другого отладка кривых ручек становится необычайно легкой (в сравннии с тем самым UB).
Ибо UB — это попытка доказать, что ты и не хотел быть программистом, а, так, случайно зашел
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Peter K., Вы писали: PK>>Насколько это pb = 0 может быть нужно и по какой причине?
К>3) Либо это лишь часть кода. А на деле там всё громоздче:
Вот так хочешь людям поведать, где и почему оно может пригодится, а Кодт уже тут, как тут.
Думаю, что обнулять указатели стоит, даже в деструкторах. Вопрос лишь в том, не будет ли компилятор производить какие-либо оптимизации тут?
Re: Обнуление указателей в деструкторе
От:
Аноним
Дата:
04.06.09 19:32
Оценка:
Здравствуйте, Peter K., Вы писали:
PK>Насколько это pb = 0 может быть нужно и по какой причине?
Про то, что в случае проблем эти самые проблемы будет искать легче уже сказали.
Но лучше это дело автоматизировать и пользоваться умными указателями.
Здравствуйте, R.O. Prokopiev, Вы писали:
ROP>Здравствуйте, Bell, Вы писали:
PK>>>Насколько это pb = 0 может быть нужно и по какой причине? B>>Абсолютно излишнее действие.
ROP>Нифига подобного. ROP>Действие очень даже нужное. ROP>Деструктор можно вызывать явно:
ROP>
ROP> A a;
ROP> a.~A();
ROP> a.~A();
ROP>
Можно, конечно. А можно и явно два раза "delete pb;" сделать, тоже никто не запрещает.