что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 11:39
Оценка:
#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;
using boost::shared_ptr;

struct resource  { 
  resource (int i0 = 0) : i(i0) {}
  int i;
  ~resource(){std::cout<<"~resource\n";}
  };

class d{
 public:
   void operator ()(resource *r){ cout<<"deleter "<<r<<endl; }
};
int main(){
  {
  shared_ptr<resource> spd(new resource(555),d());
  if(spd.get())
    cout<<spd->i<<endl;
  spd.~shared_ptr();//1
  }
  //-//
  {
  shared_ptr<resource> spnull((resource*)0);  //2
  //cout<<spnull<<endl;
  if(spnull.get())
    cout<<spnull<<" "<<spnull->i <<" "<<endl; //не попали
    }
 {
  shared_ptr<int> sp1;
  shared_ptr<int> sp2(new int(77)); //3

}
 return 0;
}

В строке /2/ ошибка

This may be due to a corruption of the heap, and indicates a bug in Boost2_2.1_2.2.exe or any of the DLLs it has loaded.

Если блок со строкой закоментировать, появляется ошибка в строке /3/.
При этом падает в файле sp_counted_base_w32.hpp в функции
    virtual void destroy() // nothrow
    {
        delete this;
    }

… а может и не падает – если нажать кнопку break , то попадаем в ассемблер из которого со временем попадаем обратно в код программы, оальше без ошибок.
Если закоментировать строку /1/ ошибка исчезает.
Что же получается, нельзя вызывать деструктор в строке/1/ [ccode] spd.~shared_ptr();//1
Почему нельзя? (VC2005)
Re: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 11:42
Оценка:
А> shared_ptr<resource> spnull((resource*)0); //2

а почему не
shared_ptr<resource> spnull;
?
Re[2]: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 11:58
Оценка:
А>а почему не
А> shared_ptr<resource> spnull;
А>?

    shared_ptr<resource> spnull((resource*)0);
    shared_ptr<resource> spnull2;


spnull — распределенный (т.е. не пустой и ничем не владеет (count!=0))
spnull2- не распределенный (т.е. пустой и ничем не владеет)

spnull    {px=0x00000000 
 +px    0x00000000
 +pn    {pi_=0x00316328 
   -pi_    0x00316328 
     __vfptr    0x0041a8dc 
       use_count_    1    
       weak_count_    1


spnull2    {px=0x00000000 
 +px    0x00000000
 +pn    {pi_=0x00000000 
   -pi_    0x00000000 
     __vfptr    CXX0030: Error: expression cannot be evaluated    
      use_count_    CXX0030: Error: expression cannot be evaluated    
      weak_count_    CXX0030: Error: expression cannot be evaluated


Это важно для операторов сравнения.
Re: что не так с shared_ptr
От: mPronin  
Дата: 09.07.08 12:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>  {
А>  shared_ptr<resource> spd(new resource(555),d());
А>  if(spd.get())
А>    cout<<spd->i<<endl;
А>  spd.~shared_ptr();//1
А>  }
А>

Сколько раз здесь вызовется деструктор?
Re[2]: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 12:33
Оценка:
Здравствуйте, mPronin, Вы писали:

P>Здравствуйте, Аноним, Вы писали:


А>>
А>>  {
А>>  shared_ptr<resource> spd(new resource(555),d());
А>>  if(spd.get())
А>>    cout<<spd->i<<endl;
А>>  spd.~shared_ptr();//1
А>>  }
А>>

P>Сколько раз здесь вызовется деструктор?

Спасибо, уже понял что перед вызовом деструктора
spd.~shared_ptr();//1

надо осободить ресурс
spd.reset();
Re[3]: что не так с shared_ptr
От: Smal Россия  
Дата: 09.07.08 12:39
Оценка:
Здравствуйте, Аноним, Вы писали:

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


P>>Здравствуйте, Аноним, Вы писали:


А>>>
А>>>  {
А>>>  shared_ptr<resource> spd(new resource(555),d());
А>>>  if(spd.get())
А>>>    cout<<spd->i<<endl;
А>>>  spd.~shared_ptr();//1
А>>>  }
А>>>

P>>Сколько раз здесь вызовется деструктор?

А>Спасибо, уже понял что перед вызовом деструктора

А>
spd.~shared_ptr();//1

А>надо осободить ресурс
spd.reset();


Неправильно. Надо просто не вызывать деструктор. В вашем коде деструктор вызывается дважды.
Это UB.
С уважением, Александр
Re[3]: что не так с shared_ptr
От: mPronin  
Дата: 09.07.08 12:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Спасибо, уже понял что перед вызовом деструктора

А>
spd.~shared_ptr();//1

А>надо осободить ресурс
spd.reset();


Не так, ~shared_ptr(), будет вызван дважды — один раз явно, второй раз неявно. Второй вызов деструктора будет произведен для невалидного объекта.

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. ]


А reset() тут не при чем, без него видимо дважды удаляется вмещаемый объект и рушится куча. При вызове reset(), объект удаляется один раз, но поведение все равно не определено.
Re[4]: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 13:12
Оценка:
P>А reset() тут не при чем, без него видимо дважды удаляется вмещаемый объект и рушится куча. При вызове reset(), объект удаляется один раз, но поведение все равно не определено.

Чтоже полечается ~shared_ptr(); вообще вызывать нельзя, соответственно обект
shared_ptr<T> Y; будет жить вечно?
Не получается дебагером зайти в файлы boost.
Re[5]: что не так с shared_ptr
От: mPronin  
Дата: 09.07.08 13:24
Оценка:
Здравствуйте, Аноним, Вы писали:

P>>А reset() тут не при чем, без него видимо дважды удаляется вмещаемый объект и рушится куча. При вызове reset(), объект удаляется один раз, но поведение все равно не определено.


А>Чтоже полечается ~shared_ptr(); вообще вызывать нельзя, соответственно обект

А>shared_ptr<T> Y; будет жить вечно?
А>Не получается дебагером зайти в файлы boost.
Деструктор для автоматических объектов вызывается неявно, при выходе последних из области видимости (ну и еще в некоторых случаях).

...
{
    shared_ptr<int> p(new int(0));
}
... //<- здесь p уже разрушен автоматически
Re[6]: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 13:36
Оценка:
P>Деструктор для автоматических объектов вызывается неявно, при выходе последних из области видимости (ну и еще в некоторых случаях).

P>
P>{
P>    shared_ptr<int> p(new int(0));
P>}
P>... //<- здесь p уже разрушен автоматически
P>


А досрочно, до выхода из области видимости, объект shared_ptr удалить нельзя?
Ждать пока он не разрушиться автоматически?
Re[7]: что не так с shared_ptr
От: Daevaorn Россия  
Дата: 09.07.08 13:38
Оценка:
Здравствуйте, Аноним, Вы писали:

P>>Деструктор для автоматических объектов вызывается неявно, при выходе последних из области видимости (ну и еще в некоторых случаях).


P>>
P>>{
P>>    shared_ptr<int> p(new int(0));
P>>}
P>>... //<- здесь p уже разрушен автоматически
P>>


А>А досрочно, до выхода из области видимости, объект shared_ptr удалить нельзя?

А>Ждать пока он не разрушиться автоматически?

Сам объект shared_ptr? зачем?
А вот сбросить ссылку в нем, через reset нужно.
Re[8]: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 13:47
Оценка:
D>Сам объект shared_ptr? зачем?
D>А вот сбросить ссылку в нем, через reset нужно.

Объект shared_ptr удалить, "зачем?" == "нельзя" или "можно" или "неизвестно"?
Re[9]: что не так с shared_ptr
От: Daevaorn Россия  
Дата: 09.07.08 14:00
Оценка:
Здравствуйте, Аноним, Вы писали:

D>>Сам объект shared_ptr? зачем?

D>>А вот сбросить ссылку в нем, через reset нужно.

А>Объект shared_ptr удалить, "зачем?" == "нельзя" или "можно" или "неизвестно"?


Зачем удалять (звать деструктор) сам объект shared_ptr если он всего лишь обертка?
Re[10]: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 14:11
Оценка:
D>Зачем удалять (звать деструктор) сам объект shared_ptr если он всего лишь обертка?

Ну а если их много и они больше не нужны, то чем они владели удалили, а их(shared_ptr) оставили, а они не такие и тривиальные.
Re[11]: что не так с shared_ptr
От: VoidEx  
Дата: 09.07.08 14:13
Оценка:
Здравствуйте, Аноним, Вы писали:

D>>Зачем удалять (звать деструктор) сам объект shared_ptr если он всего лишь обертка?


А>Ну а если их много и они больше не нужны, то чем они владели удалили, а их(shared_ptr) оставили, а они не такие и тривиальные.


Аллоцируй тогда на стеке и пользуйся, только смысла в них не будет, ибо удалять придётся ручками всегда (почему компилятор не сможет автоматически — сам подумай), тогда уж проще тупо указатель хранить.
Re[12]: что не так с shared_ptr
От: Аноним  
Дата: 09.07.08 14:38
Оценка:
draft Working Draft, Standard for Programming Language C++.

20.6.12.2.2 shared_ptr destructor [util.smartptr.shared.dest]
~shared_ptr();
1 Effects:
— If *this is empty or shares ownership with another shared_ptr
instance (use_count() > 1), there are no side effects.
— Otherwise, if *this owns a pointer p and a deleter d, d(p) is called.
— Otherwise, *this owns a pointer p, and delete p is called.

1 Эффект:
— Если *this пуст или совместно владеет ресурсом с другим shared_ptr (use_count ()> 1),
это /~shared_ptr();/ не имеет эфекта
— Иначе, если *this владеет указателем p, и удалителелем d, вызывают d (p)
— Иначе, *this владеет указателем p, вызывается delete p .

так что похоже все не правы
{
  shared_ptr<resource> spd(new resource(555),d());
  if(spd.get())
    cout<<spd->i<<endl;
  spd.~shared_ptr();//1 - Иначе, если *this  владеет указателем p, и удалителелем d, вызывают d (p) 
}


ошибки быть не должно, тогда чего ругается VC
Re[9]: что не так с shared_ptr
От: bkat  
Дата: 09.07.08 15:11
Оценка:
Здравствуйте, Аноним, Вы писали:

D>>Сам объект shared_ptr? зачем?

D>>А вот сбросить ссылку в нем, через reset нужно.

А>Объект shared_ptr удалить, "зачем?" == "нельзя" или "можно" или "неизвестно"?


shared_ptr тут ну совсем не причем.
Забудь про shared_ptr и просто подумай нафига удалять объект два раза.

Что ты ожидаешь, например от такого?
{
   string myCoolStringObject("a попробую-ка я удалить строку два раза");
   myCoolStringObject.~string();
}


А от такого?
{
   MySuperCoolClass myCoolObject;
   myCoolObject.~MySuperCoolClass();
}


В общем попробуй абстрагироваться от shared_ptr и взгляни на ситуацию с точки зрения
объектов, конструкторов и деструкторов.
Re[7]: что не так с shared_ptr
От: mPronin  
Дата: 10.07.08 07:15
Оценка:
Здравствуйте, Аноним, Вы писали:

P>>Деструктор для автоматических объектов вызывается неявно, при выходе последних из области видимости (ну и еще в некоторых случаях).


P>>
P>>{
P>>    shared_ptr<int> p(new int(0));
P>>}
P>>... //<- здесь p уже разрушен автоматически
P>>


А>А досрочно, до выхода из области видимости, объект shared_ptr удалить нельзя?

А>Ждать пока он не разрушиться автоматически?

Явно звать деструктор можно — здесь
Автор: remark
Дата: 18.12.06
. Только зачем?
Re[13]: что не так с shared_ptr
От: mPronin  
Дата: 10.07.08 07:42
Оценка:
Здравствуйте, Аноним, Вы писали:

А>draft Working Draft, Standard for Programming Language C++.

А>

20.6.12.2.2 shared_ptr destructor [util.smartptr.shared.dest]
А> ~shared_ptr();
А>1 Effects:
А>— If *this is empty or shares ownership with another shared_ptr
А> instance (use_count() > 1), there are no side effects.
А>— Otherwise, if *this owns a pointer p and a deleter d, d(p) is called.
А>— Otherwise, *this owns a pointer p, and delete p is called.


И? Реализация деструктора никак не отменяет тот факт, что он будет вызван дважды.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.