Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Логика удаления map


Автор: cupper 31.5.2011, 18:47
Встретил в чужом коде непонятную мне логическую конструкцию
Код

ClassX::~ClassX()
{
    SessionsMap sessions( sessions_ );
    sessions_.clear();

    for_each(sessions.begin(), sessions.end(), Utils::ReleaseSecond());
}

Код

typedef std::map<std::string, Session*> SessionsMap;
struct ReleaseSecond{
        template<typename T1, typename T2>
            void operator()(const std::pair<T1, T2>& p) {
                 p.second->release();
        }
    };


И озадачился сакральным смыслом того что перед удалением мапы, его копируют во временный мап, потом подчищаю оригинал. И После проводят корректное удаление указателей на Session через временно созданные map.

Автор: boostcoder 31.5.2011, 19:39
стандартная практика в асинхронном/многопоточном коде.
т.е. detach`имся от sessions_, в копии вызывается release() для каждого Session, и в тоже самое время, sessions_ может заполняться новыми Session`ами.

Добавлено через 6 минут
Цитата(boostcoder @  31.5.2011,  19:39 Найти цитируемый пост)
detach`имся от sessions_

все равно странно то, почему никак не защищена операция копирования... если моя мысль верна.

Автор: azesmcar 1.6.2011, 08:11
Цитата(boostcoder @  31.5.2011,  19:39 Найти цитируемый пост)
стандартная практика в асинхронном/многопоточном коде.

А что, там планировалось асинхронно вызванному деструктору выполнять еще какие-то операции над объектом? smile 

Цитата(cupper @  31.5.2011,  18:47 Найти цитируемый пост)
И озадачился сакральным смыслом того что перед удалением мапы, его копируют во временный мап, потом подчищаю оригинал.

Мало ли что, может результат copy-paste-а. У нас таких кодов столько, что если каждым озадачиваться... smile 

Автор: cupper 1.6.2011, 08:37
Цитата(boostcoder @ 31.5.2011,  19:39)
стандартная практика в асинхронном/многопоточном коде.
т.е. detach`имся от sessions_, в копии вызывается release() для каждого Session, и в тоже самое время, sessions_ может заполняться новыми Session`ами.

в деструкторе О_о ? Дабы развеять все мифы, переменная session_ находится сугубо только в этом классе и на ружу не как не торчит. 

Наверно все таки это "кодоляп" (от "киноляп"). Решил подстраховаться от возможной своей глупости.

Автор: boostcoder 1.6.2011, 08:44
Цитата(azesmcar @  1.6.2011,  08:11 Найти цитируемый пост)
что, там планировалось асинхронно вызванному деструктору выполнять еще какие-то операции над объектом?

почему нет?

Цитата(cupper @  1.6.2011,  08:37 Найти цитируемый пост)
в деструкторе О_о ? Дабы развеять все мифы, переменная session_ находится сугубо только в этом классе и на ружу не как не торчит.

ну тогда хз..

Автор: azesmcar 1.6.2011, 08:53
Цитата(boostcoder @  1.6.2011,  08:44 Найти цитируемый пост)
почему нет?

Потому-что проводить какие-либо манипуляции с объектом, который на данный момент удаляется, немного...мммм...необычно. smile 

Автор: boostcoder 1.6.2011, 09:37
что в этом коде необычного?
Код

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
#include <iostream>

struct Session {
   void release() {}
};

typedef std::map<std::string, Session*> SessionsMap;

struct ReleaseSecond{
   template<typename T1, typename T2>
   void operator()(const std::pair<T1, T2>& p) {
      p.second->release();
   }
};

struct ClassX {
   ~ClassX () {
      SessionsMap sessions(sessions_);
      std::for_each(sessions.begin(), sessions.end(), ReleaseSecond());
   }

   SessionsMap sessions_;
};

int main() {
   boost::shared_ptr<ClassX> ptr(new ClassX);
   boost::thread t([ptr]() {;});
}

http://liveworkspace.org/code/741dcee654aee3ac269bf5c96da8adad

если опустить это:
Цитата(cupper @  1.6.2011,  08:37 Найти цитируемый пост)
переменная session_ находится сугубо только в этом классе и на ружу не как не торчит

вполне себе законный код, если предположить что объекты ClassX "живут" в каком-то контейнере обернутые в shared_ptr, и при необходимости "выбрасываются" из него.

или что?

Автор: azesmcar 1.6.2011, 09:54
boostcoder

Разница в том, что в твоем коде объект не будет удаляться, пока с ним работают, так-как shared_ptr будет держать его в живом состоянии, пока поток на него ссылается, а значит работы с удаленном объектом здесь не будет, а если

Цитата(azesmcar @  1.6.2011,  08:53 Найти цитируемый пост)
проводить какие-либо манипуляции с объектом, который на данный момент удаляется

то закончиться это как ни странно segmentation fault -ом.

Автор: boostcoder 1.6.2011, 09:59
Цитата(azesmcar @  1.6.2011,  09:54 Найти цитируемый пост)
закончиться это как ни странно segmentation fault -ом

оно и ясно.
похоже не правильно поняли изначально друг-друга..

Добавлено через 2 минуты и 27 секунд
но если sessions_ приватный, смысл создания копии в деструкторе все равно не понятен..

cupper, а друзей у него нет?

Автор: bsa 1.6.2011, 10:38
кстати. очень "интересный" подход. я бы это сделал через swap - операция значительно быстрее, чем две (копирование и очистка).

Автор: mes 1.6.2011, 11:55
а держит ли _second_ ссылку/указатель на classX или SessionsMap?

Автор: xvr 1.6.2011, 16:46
Цитата(mes @ 1.6.2011,  11:55)
а держит ли _second_ ссылку/указатель на classX или SessionsMap?

Скорее всего держит.  smile 
Вполне стандартная ситуация, когда какие то объекты [Session] регистрируются (и дерегестрируются) в каком то менеджере [ClassX], и процесс дерегистрации запускается автоматом при удалении объекта [Session] и при этом производятся какие то нетривиальные действия в менеджере [ClassX].
Удаление скопом всего списка зарегистрированных объектов перед разрушением самого менеджера позволит не выполнять этих самых нетривиальных действий, а так же делать вид, что никаких объектов уже в менеджере нет (если эти самые Session при удалении полезут исследовать содержимое ClassX)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)