Я уверен, что это ошибка. Если вы свернете его до крошечного примера, например ::100100
void boundFunction(int) { }
typedef boost::signal0<void> LeakSignalType;
LeakSignalType::slot_type aSlot = boost::bind(&::boundFunction, 1);
LeakSignalType sig1, sig2;
sig1.connect(aSlot);
sig2.connect(aSlot);
и проследите распределения, вы обнаружите, что один объект (boost::signals::detail::signal_base_impl::iterator
), расположенный в строке 75 boost/lib/signals/src/signal_base.cpp
, не освобожден.
// Allocate storage for an iterator that will hold the point of
// insertion of the slot into the list. This is used to later remove
// the slot when it is disconnected.
std::auto_ptr<iterator> saved_iter(new iterator);
На первом connect
этот итератор присоединен к свежему объекту соединения, где signal_data
равно NULL:
data->watch_bound_objects.get_connection()->signal_data =
saved_iter.release();
На втором connect
, однако, один и тот же объект соединения используется повторно, и та же самая строка слепо перезаписывает исходное значение указателя. Второй объект очищен, а первый нет.
В качестве проверки точка останова в signal_base_impl::slot_disconnected
, единственном месте, где очищается signal_data
, срабатывает только один раз.
Я выследил это в 1.39.0, но похоже, что это то же самое в 1.40.0.
Вы можете изменить boost::signals::detail::signal_base_impl::connect_slot
, чтобы очистить любое предыдущее значение итератора, найденное в поле signal_data
существующего соединения, если вы можете сделать такое изменение и запустить пользовательскую сборку Boost.
Может быть, лучше просто убедиться, что вы устанавливаете их только фиксированное количество раз, и жить с небольшими утечками памяти, которые, как вы знаете, со временем не увеличатся.
Обновление:
Я собирался отправить это на баг-трекер, но он уже там. Однако это гораздо меньший контрольный пример.
https://svn.boost.org/trac/boost/ticket/738
Открыт 3 года назад, не связан ни с одним этапом: - [