2008年在VC快递下,我在使用Loki::Singleton,Loki::SmartPtr,和std::时遇到了一个问题。以下是我的消息来源。
#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?
提前谢谢。
发布于 2009-07-07 19:40:16
当您使用VC时,您应该能够以调试模式运行您的代码,分步运行stp (F10,F11)来查看代码的中断位置。
无论如何,查看Loki单例编码,似乎错误来自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实例销毁时被销毁(指针而不是实例),然后LifetimePolicy尝试调用它的DestroySingleton()函数.
但我可能错了,你得检查一下。
发布于 2009-07-07 19:55:19
IMR,您不能在stl容器中使用某些智能指针,而这正是发生的问题。如果内存可用,则与stl容器如何复制不符合智能指针预期使用方式的值有关。
发布于 2021-09-02 07:43:48
Loki的智能指针在STL容器中没有问题。如果您以这样的方式重写此示例:
#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 ()
{
Loki::SmartPtr<Foo> root = new Foo;
std::cout << "Start" << std::endl ;
// SingletonFoo::Instance().add() ;
root->add();
std::cout << "End" << std::endl ;
}它的工作没有任何问题。
这里发生的情况是,同一个类不应该同时作为Loki::Singleton和Loki::SmartPtr使用--它是在Loki::Singleton中直接创建和销毁的,但是Loki::SmartPtr的引用计数是被维护的。
但是,如果您使用Loki::SmartPtr<Foo>作为Loki::Singleton的参数,它可以工作!您必须对代码进行的唯一修改是对Loki::CreateUsingNew类进行专门化,以创建使用新创建的Foo初始化的Loki::SmartPtr<Foo>。
#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 () {
}
};
namespace Loki {
template<class T>
struct CreateUsingNew<class Loki::SmartPtr<T>> {
static Loki::SmartPtr<T>* Create()
{ return new Loki::SmartPtr<T>(new T); }
static void Destroy(Loki::SmartPtr<T>* p)
{ delete p; }
};
}
typedef Loki::SingletonHolder<Loki::SmartPtr<Foo>> SingletonFoo ;
int main ()
{
std::cout << "Start" << std::endl ;
SingletonFoo::Instance()->add() ;
std::cout << "End" << std::endl ;
}https://stackoverflow.com/questions/1094276
复制相似问题