удаление вызывающего объекта, и непонятка с размоткой стека
От: niXman Ниоткуда https://github.com/niXman
Дата: 13.03.13 13:27
Оценка:
приветствую!

имеется такой код:
#include <iostream>
#include <memory>
#include <map>

#include <boost/format.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp>

/****************************************************************************/

// forward
struct item;

/****************************************************************************/

struct container {
   container(boost::asio::io_service &ios);

   void delete_me(int id) {
      auto it = map.find(id);
      BOOST_ASSERT(it != map.end());
      std::cerr << boost::format("before erase item %1% (%2%)")
         % id % it->second.get()
      << std::endl;
      
      map.erase(it);

      std::cerr << boost::format("after erase item %1% (%2%)")
         % id % it->second.get()
      << std::endl;
   }
   
   boost::asio::io_service &_ios;
   std::map<int, std::shared_ptr<item>> map;
};

/****************************************************************************/

struct item {
   item(int id, boost::asio::io_service &ios, container& cont)
      :_id(id)
      ,_timer(ios)
   {
      const int time = (id==0 ? 2 : 1);
      
      std::cerr << boost::format("item %1% created. time=%2% (%3%)") % id % time % this << std::endl;
      
      _timer.expires_from_now(boost::posix_time::seconds(time));
      _timer.async_wait(
         [this, &cont, id](const boost::system::error_code&) {
            std::cerr << boost::format("time-out for item %1% expired, request for delete it (%2%)")
               % id % this
            << std::endl;
            
            cont.delete_me(id);
         }
      );
   }
   
   ~item() {
      std::cerr << boost::format("dtor item %1% (%2%)")
         % _id % this
      << std::endl;
   }
   
   int _id;
   boost::asio::deadline_timer _timer;
};

/****************************************************************************/

container::container(boost::asio::io_service &ios)
   :_ios(ios)
{
   auto p1 = new item(0, _ios, *this);
   map[0].reset(p1);
   auto p2 = new item(1, _ios, *this);
   map[1].reset(p2);
}

/****************************************************************************/

int main() {
   boost::asio::io_service ios;
   container cont(ios);
   ios.run();
   std::cerr << std::endl << "finished!" << std::endl;
}

/****************************************************************************/

http://liveworkspace.org/code/2brGJU$0

что выполняет код?: container создает некоторое кол-во объектов типа item. item`ы в свою очередь, удаляются по событиям производимым в ответ на сетевое взаимодействие, т.е. асинхронно. (тут в примере — по таймеру)
в чем вопрос?: вопрос в том, что как вы можете видеть в выводе(ниже), когда item по адресу 0xda6370 зовет 'container::delete_me(id)' для себя же, что происходит со стеком? стек ведь должен размотаться до уровня, из которого вызвали 'container::delete_me(id)', но объект же удалится раньше чем стек размотается %)

item 0 created. time=2 (0xda6110)
item 1 created. time=1 (0xda6370)
time-out for item 1 expired, request for delete it (0xda6370)
before erase item 1 (0xda6370)
dtor item 1 (0xda6370)
after erase item 1 (0xda6370)
time-out for item 0 expired, request for delete it (0xda6110)
before erase item 0 (0xda6110)
dtor item 0 (0xda6110)
after erase item 0 (0xda6110)

finished!


спасибо.


зы
я плохо знаю ассемблер .и наверное по этому и не понимаю, валиден ли код или нет...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.