2009-07-07 6 views
0

Я столкнулся с проблемой при использовании Loki :: Singleton, Loki :: SmartPtr и зОго :: вектор под VC express 2008. Следующим является мой источник.Странная проблема памяти о Loki :: Singleton, Loki :: SmartPtr и станд :: вектор

#include <iostream> 
#include <vector> 
#include <loki/Singleton.h> 
#include <loki/SmartPtr.h> 

class Foo { 
    public: 
    std::vector<Loki::SmartPtr<Foo>> children ; 
    void add() { 
     Loki::SmartPtr<Foo> f = new Foo ; 
     children.push_back(f) ; 
    } 
    Foo() { 
    } 
    ~Foo() { 
    } 
} ; 

typedef Loki::SingletonHolder<Foo> SingletonFoo ; 

int main() 
{ 
    std::cout << "Start" << std::endl ; 
    SingletonFoo::Instance().add() ; 
    std::cout << "End" << std::endl ; 
} 

Компиляция и связывание не имеет никаких проблем, но после завершения программы, ошибка выскакивает:

Windows has triggered a breakpoint in test.exe. 
This may be due to a corruption of the heap, which indicates a bug in test.exe or any of the DLLs it has loaded. 
This may also be due to the user pressing F12 while test.exe has focus. 
The output window may have more diagnostic information. 

Это кажется часть памяти удаляется дважды, я совсем не уверен. Это ошибка VC или я пропустил Loki?

Заранее спасибо.

ответ

1

Как вы используете VC, вы можете запустить свой код в режиме отладки, шаг за шагом (F10, F11), чтобы увидеть, где он ломается.

Во всяком случае, глядя на Loki singleton code, кажется, что ошибка происходит от утверждают в SingletonHolder :: DestroySingleton():

SingletonHolder<T, CreationPolicy, L, M, X>::DestroySingleton() 
00837  { 
00838   assert(!destroyed_); // there, but it's a wild guess 
00839   CreationPolicy<T>::Destroy(pInstance_); 
00840   pInstance_ = 0; 
00841   destroyed_ = true; 
00842  } 

Эта функция, кажется, называется по LifetimePolicy (здесь DefaultLifetime), так как это код предлагает:

00800  template 
00801  < 
00802   class T, 
00803   template <class> class CreationPolicy, 
00804   template <class> class LifetimePolicy, 
00805   template <class, class> class ThreadingModel, 
00806   class MutexPolicy 
00807  > 
00808  void SingletonHolder<T, CreationPolicy, 
00809   LifetimePolicy, ThreadingModel, MutexPolicy>::MakeInstance() 
00810  { 
00811   typename ThreadingModel<SingletonHolder,MutexPolicy>::Lock guard; 
00812   (void)guard; 
00813   
00814   if (!pInstance_) 
00815   { 
00816    if (destroyed_) 
00817    { 
00818     destroyed_ = false; 
00819     LifetimePolicy<T>::OnDeadReference(); 
00820    } 
00821    pInstance_ = CreationPolicy<T>::Create(); 
00822    LifetimePolicy<T>::ScheduleDestruction(pInstance_, // here 
00823     &DestroySingleton); 
00824   } 
00825  } 

Я не знаю, почему он вызывается дважды, но я предполагаю, что указатель на синглтон сначала уничтожен (указатель, а не экземпляра) об уничтожении экземпляра SingletonHolder, а затем LifetimePoli cy попытайтесь назвать его функцией DestroySingleton() ...

Но я, возможно, ошибаюсь, вам придется это проверить.

1

IMR, вы не можете использовать определенные интеллектуальные указатели в stl-контейнерах, и это точная проблема, которая возникает. Если память обслуживается, это связано с тем, как контейнеры stl копируют значения, не соответствующие тому, как предполагается, что смарт-указатели будут использоваться.

+0

Я перепробовал использование Loki :: SmartPtr, политика по умолчанию - это счетчик ссылок, который имеет такое же поведение с Boost :: shared_ptr, поддерживает семантическое значение и может использоваться в контейнере STL. Есть ли другие возможные объяснения? Большое спасибо. – yoco

+0

Если вы подозреваете, что ваши объекты дважды удаляются, попытались ли вы придерживаться контрольных точек в своем деструкторе и проверить стек вызовов? –

 Смежные вопросы

  • Нет связанных вопросов^_^