Re[2]: Обнуление указателей в деструкторе
От: Ulitka США http://lazarenko.me
Дата: 04.06.09 20:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Peter K., Вы писали:


PK>>Насколько это pb = 0 может быть нужно и по какой причине?


А>Про то, что в случае проблем эти самые проблемы будет искать легче уже сказали.

А>Но лучше это дело автоматизировать и пользоваться умными указателями.

А за "умные" указатели в иных местах и больно бьют.
Re[3]: Обнуление указателей в деструкторе
От: Аноним  
Дата: 04.06.09 20:40
Оценка: +4
Здравствуйте, Ulitka, Вы писали:

U>А за "умные" указатели в иных местах и больно бьют.


Типа "обжегшись на молоке, дуют на воду"?
Ну есть такие, которые тупо отсекают многие полезные вещи.
Фанатизм и фундаментализм можно обсуждать долго, но уже не интересно.
Re: Обнуление указателей в деструкторе
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.06.09 20:08
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>Иногда приходится нечто подобное:


PK>Насколько это pb = 0 может быть нужно и по какой причине?

PK>(Извините, если уже было, не нашел).

В далеком детстве, я как-то раз раступил на грабли BCB, которые дважды вызывал деструктор статического объекта. До сих пор вспоминаю, и, из вариантов — обнулять / не обнулять, выбираю — обнулять

Вообще, в отладочном коде, иногда полезно в деструкторе возводить какой-нибуть отладочный флаг объекта "типа я разрушен". А в методах его проверять. Незаменимая штука в нетривиальных объектах, у которых подобъекты могут дергать методы родителя

----
К проблемам многопоточного кода это имеет очень косвенное отношение.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: Обнуление указателей в деструкторе
От: yarus23  
Дата: 07.06.09 11:24
Оценка:
U>А за "умные" указатели в иных местах и больно бьют.

Это где же бьют за boost::scoped_ptr, скажи, я туда ни за что не пойду работать.
Re[3]: Обнуление указателей в деструкторе
От: jazzer Россия Skype: enerjazzer
Дата: 07.06.09 13:21
Оценка: :)
Здравствуйте, Ulitka, Вы писали:

U>А за "умные" указатели в иных местах и больно бьют.


имя "иного места" в студию!
Народ должен знать, куда не отправлять резюме.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Обнуление указателей в деструкторе
От: hramovnik  
Дата: 10.06.09 10:11
Оценка:
Здравствуйте, Bell, Вы писали:

ROP>>Действие очень даже нужное.

B>Просвяти, в каких это случаях оно такое нужное?

Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.
Re[5]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 10.06.09 10:24
Оценка:
Здравствуйте, hramovnik, Вы писали:

ROP>>>Действие очень даже нужное.

B>>Просвяти, в каких это случаях оно такое нужное?

H> Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.

Ничего не понял. Можно на примере?
Любите книгу — источник знаний (с) М.Горький
Re[6]: Обнуление указателей в деструкторе
От: hramovnik  
Дата: 10.06.09 10:50
Оценка: :)
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, hramovnik, Вы писали:


ROP>>>>Действие очень даже нужное.

B>>>Просвяти, в каких это случаях оно такое нужное?

H>> Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.

B>Ничего не понял. Можно на примере?


Можно.

class A
{
public:
A(type *p = NULL)
   : ptr(p)
{};

~A()
{
 if(ptr)
 {
   delete ptr;
   ptr = NULL;
 }
};

type *ptr;
};

A some_function()
{
  A a(new type(/*init*/));
  /*some code*/
  return a;
}

void main()
{
  A a = some_function();
}
Re[7]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 10.06.09 11:01
Оценка: +1
Здравствуйте, hramovnik, Вы писали:

B>>Ничего не понял. Можно на примере?

H>Можно.
...

Я почему-то именно про это и подумал
Скажи, как обнуление в одном экземпляре повлияет на другой экземпляр?

ЗЫ
Можно было бы хотя бы раз запустить примерчик-то...
Любите книгу — источник знаний (с) М.Горький
Re[3]: Обнуление указателей в деструкторе
От: mike_rs Россия  
Дата: 10.06.09 11:01
Оценка:
Здравствуйте, Plague, Вы писали:

P>Вот так хочешь людям поведать, где и почему оно может пригодится, а Кодт уже тут, как тут.

P>Думаю, что обнулять указатели стоит, даже в деструкторах. Вопрос лишь в том, не будет ли компилятор производить какие-либо оптимизации тут?

кстати компилер вполне может выкинуть такой код. Вспомнился Шнайер (?) с примеров когда в функции шифрование перед выходом обнулялся ключ через memset, типа чтобы все секурно и на стеке не оставить данные, а умный компилер, видя что к обнуляемым локальным данным дальше обрашений нет выкидывал этот memset. В некоторых криптолибах это дело специальным образом обходится.
Re[7]: Обнуление указателей в деструкторе
От: Caracrist https://1pwd.org/
Дата: 10.06.09 11:14
Оценка:
Здравствуйте, hramovnik, Вы писали:

H>Здравствуйте, Bell, Вы писали:


B>>Здравствуйте, hramovnik, Вы писали:


ROP>>>>>Действие очень даже нужное.

B>>>>Просвяти, в каких это случаях оно такое нужное?

H>>> Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.

B>>Ничего не понял. Можно на примере?


H>Можно.


H>
H>class A
H>{
H>public:
H>A(type *p = NULL)
H>   : ptr(p)
H>{};

H>~A()
H>{
H> if(ptr)
H> {
H>   delete ptr;
H>   ptr = NULL;
H> }
H>};

H>type *ptr;
H>};

H>A some_function()
H>{
H>  A a(new type(/*init*/));
H>  /*some code*/
H>  return a;
H>}

H>void main()
H>{
H>  A a = some_function();
H>}
H>


второй умрёт даже если было обнуление.
Значение указателя скопируется в другой объект ещё до обнуления, и в деструкторе второго будет пытаться удалить уже удалённый объект.
Два деструктора сами по себе(не явно) никогда не вызовутся.
~~~~~
~lol~~
~~~ Single Password Solution
Re: Обнуление указателей в деструкторе
От: Kingofastellarwar Украина  
Дата: 10.06.09 12:22
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>Иногда приходится нечто подобное:


PK>
PK>class B;

PK>class A {
PK>   B * pb;
PK>public:
PK>   A() : pb(new B()) {}
PK>   ~A()
PK>   {
PK>      delete pb;
PK>      pb = 0;
PK>   }
PK>};
PK>

PK>Насколько это pb = 0 может быть нужно и по какой причине?
PK>(Извините, если уже было, не нашел).

иногда надо, и с таким сталкивался, когда в деструкторе стоит эвент говорящий что объект уничтожается, а обработчик может обратится к этой переменной, а то и косвенно вызвать деструктор еще раз
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[7]: Обнуление указателей в деструкторе
От: ffk  
Дата: 11.06.09 06:38
Оценка:
Здравствуйте, Ulitka, Вы писали:

U>Здравствуйте, R1K0, Вы писали:


RK>>AV отладить куда проще


U>А вот и нет. Точно так же просто, как и обращение к уже "удаленному" сегменту памяти.

Для релиза не факл, а AV 100%
Re[2]: Обнуление указателей в деструкторе
От: ffk  
Дата: 11.06.09 06:42
Оценка:
Здравствуйте, Kingofastellarwar, Вы писали:

K>иногда надо, и с таким сталкивался, когда в деструкторе стоит эвент говорящий что объект уничтожается, а обработчик может обратится к этой переменной, а то и косвенно вызвать деструктор еще раз


Ужас! А как же нормальная синхронизация?
Re[3]: Обнуление указателей в деструкторе
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 11.06.09 07:53
Оценка:
Здравствуйте, ffk, Вы писали:

ffk>Здравствуйте, Kingofastellarwar, Вы писали:


K>>иногда надо, и с таким сталкивался, когда в деструкторе стоит эвент говорящий что объект уничтожается, а обработчик может обратится к этой переменной, а то и косвенно вызвать деструктор еще раз


ffk>Ужас! А как же нормальная синхронизация?


Не понял о какой именно синхронизации ты говоришь, но как чел, у которого были такие забубенные хороводы объектов (и лично наступавшего на подобные грабли), могу сказать что деструктор любого объекта, который держит в себе другие объекты и обрабатывает их уведомления, перво-наперво должен отключаться от уведомлений дочерних объектов. В особо "тяжелых" случаях, нужно еще форсированно отключить всех собственных подписчиков.

До кучи (для упрощения выискивания причины падений) нужно завести флаг о котором я тут раньше упомянул ...

Вот, надыбал в мемуарах
TREGDataContainer::~TREGDataContainer()
{
 DEBUG_CODE(m_sobj_is_destroyed=true);

 this->ResetHandlers();

 //отключаемся от уведомлений вложенных объектов
 Folders              .ResetHandlers();
 Persons              .ResetHandlers();
 Things               .ResetHandlers();
 PersonDealRefs       .ResetHandlers();
 ThingDealRefs        .ResetHandlers();
 CommonDocuments      .ResetHandlers();
 Units                .ResetHandlers();
 Deals                .ResetHandlers();
 UnitDealLinks        .ResetHandlers();
 UnitRightLinks       .ResetHandlers();
 DealCMDocLinks       .ResetHandlers();
 UnitCMDocLinks       .ResetHandlers();

 CurrentDeal          .ResetHandlers();
 CurrentThingDealRef  .ResetHandlers();

 DESTROY_COMPONENT()
}//~TREGDataContainer

void TREGDataContainer::ResetHandlers()
{
 OnDataChange                =NULL;
 OnCMDocumentChange          =NULL;
 OnDealChange                =NULL;
 OnUnitChange                =NULL;

 OnCurrentThingDealRefChange =NULL;
}//ResetHandlers
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[4]: Обнуление указателей в деструкторе
От: _wf Россия  
Дата: 15.06.09 07:28
Оценка:
ROP>>Действие очень даже нужное.
B>Просвяти, в каких это случаях оно такое нужное?

Г-н Саттер даёт следующий пример:

void f()
{
    T t(1);
    T & rt = t;
    // <1> действия с t или rt
    t.~T();
    new (&t) T(2);
    // <2> действия с t или rt
    // автоуничтожение t
}


И пишет, что данный код абсолютно легален и корректен до тех пор, пока есть
гарантия того, что выполнение "доберётся" до блока <2>:
если конструктор T(2) кинет исключение, будет автоматически вызван деструктор
для уже уничтоженного объекта
Re[5]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 15.06.09 08:13
Оценка: +2
Здравствуйте, _wf, Вы писали:

B>>Просвяти, в каких это случаях оно такое нужное?


_wf>Г-н Саттер даёт следующий пример:


_wf>
_wf>void f()
_wf>{
_wf>    T t(1);
_wf>    T & rt = t;
_wf>    // <1> действия с t или rt
_wf>    t.~T();
_wf>    new (&t) T(2);
_wf>    // <2> действия с t или rt
_wf>    // автоуничтожение t
_wf>}
_wf>


_wf>И пишет, что данный код абсолютно легален и корректен до тех пор, пока есть

_wf>гарантия того, что выполнение "доберётся" до блока <2>:
_wf>если конструктор T(2) кинет исключение, будет автоматически вызван деструктор
_wf>для уже уничтоженного объекта

Опять не понял

12.4/14
...
the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8).
...


Я конечно понимаю, что в ряде случаев это самое неопределенное поведение является вполне определенным — но закладываться на это без крайней на то необходимости — не есть хорошо, ИМХО.
В данном случае, очевидно, ты имеешь ввиду то обстоятельство, что на некоторых платформах при обнулении указателя в первом вызове деструктора, при повторном вызове деструктора ничего страшного не произойдет. Как я уже сказал — повторный вызов деструктора — это уже UB, и лично меня совершенно не успокаивает тот факт, что в данный момент по счастливому стечению обстоятельств ничего не сломалось и не упало.
Любите книгу — источник знаний (с) М.Горький
Re[6]: Обнуление указателей в деструкторе
От: _wf Россия  
Дата: 16.06.09 08:18
Оценка:
_wf>>
_wf>>void f()
_wf>>{
_wf>>    T t(1);
_wf>>    T & rt = t;
_wf>>    // <1> действия с t или rt
_wf>>    t.~T();
_wf>>    new (&t) T(2);
_wf>>    // <2> действия с t или rt
_wf>>    // автоуничтожение t
_wf>>}
_wf>>


B>Опять не понял

B>

B>12.4/14
B>...
B>the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8).
B>...


Противоречия стандарта вышеприведённому коду не вижу. Время жизни объекта t, объявленного в первой строке функции,
заканчивается (с точки зрения компилятора) перед выходом из функции. Компилятор исправно выполняет свою работу
(а именно — разрушение объекта) как при нормальном, так и при "исключительном" выходе из функции.

Противоречие в том, что в середине функции объект искуственно переконструируется (но это проблема разработчика,
а не компилятора, и выбор такого решения исключительно на совести первого), и, если повторное конструирование
не удаётся (конструктор выбрасывает исключение), происходит, по сути, двойной вызов деструктора.
И в данном конкретном случае, проверка на повторный вызов деструктора будет весьма кстати. Остальное дело
десятое.

Всё это не отменяет того, что для того, чтобы написать подобное, нужны действительно веские причины и полное
понимание нюансов и путей выполнения. Проверка "на всякий случай" имхо — вопрос спорный.
Re[7]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 16.06.09 09:20
Оценка:
Здравствуйте, _wf, Вы писали:

_wf>Противоречия стандарта вышеприведённому коду не вижу.

Об этом вроде никто и не говорил
_wf>Время жизни объекта t, объявленного в первой строке функции,
_wf>заканчивается (с точки зрения компилятора) перед выходом из функции. Компилятор исправно выполняет свою работу
_wf>(а именно — разрушение объекта) как при нормальном, так и при "исключительном" выходе из функции.

_wf>Противоречие в том, что в середине функции объект искуственно переконструируется

В С++ нет такого понятоя — "переконструирование объекта".

_wf>...(но это проблема разработчика,

_wf>а не компилятора, и выбор такого решения исключительно на совести первого), и, если повторное конструирование
_wf>не удаётся (конструктор выбрасывает исключение), происходит, по сути, двойной вызов деструктора.
По сути происходит принудительное окончание времени жизни объекта при явном вызове деструктора. Если конструирование нового объекта на месте старого прошло неудачно, то мы имеем вызов деструктора для уже мертвого объекта — UB.

_wf>И в данном конкретном случае, проверка на повторный вызов деструктора будет весьма кстати. Остальное дело

_wf>десятое.
Если считать нормальной ситуацией неопределенное поведение программы — то действительно, все это дело десятое. В добрый путь.
Любите книгу — источник знаний (с) М.Горький
Re[8]: Обнуление указателей в деструкторе
От: _wf Россия  
Дата: 16.06.09 12:16
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, _wf, Вы писали:


_wf>>Противоречия стандарта вышеприведённому коду не вижу.

B>Об этом вроде никто и не говорил
_wf>>Время жизни объекта t, объявленного в первой строке функции,
_wf>>заканчивается (с точки зрения компилятора) перед выходом из функции. Компилятор исправно выполняет свою работу
_wf>>(а именно — разрушение объекта) как при нормальном, так и при "исключительном" выходе из функции.

_wf>>Противоречие в том, что в середине функции объект искуственно переконструируется

B>В С++ нет такого понятоя — "переконструирование объекта".

Никто и не говорит про понятия C++ — придираться к словам не обязательно.
Мог написать вашим штилем —
"происходит принудительное окончание времени жизни объекта при явном вызове деструктора"
как в этом ключе завернуть про его reborn даже не знаю.

_wf>>...(но это проблема разработчика,

_wf>>а не компилятора, и выбор такого решения исключительно на совести первого), и, если повторное конструирование
_wf>>не удаётся (конструктор выбрасывает исключение), происходит, по сути, двойной вызов деструктора.
B>По сути происходит принудительное окончание времени жизни объекта при явном вызове деструктора. Если конструирование нового объекта на месте старого прошло неудачно, то мы имеем вызов деструктора для уже мертвого объекта — UB.

Вполне предсказуемое такое U/B, соответственно, может быть проконтроллировано.

_wf>>И в данном конкретном случае, проверка на повторный вызов деструктора будет весьма кстати. Остальное дело

_wf>>десятое.
B>Если считать нормальной ситуацией неопределенное поведение программы — то действительно, все это дело десятое. В добрый путь.

Моё отношение к ситуации, в общем-то, было в последнем абзаце.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.