Loki::Singleton、Loki::SmartPtr 和 std::vector 奇怪的内存问题
我在 VC Express 2008 下使用 Loki::Singleton、Loki::SmartPtr 和 std::vector 时遇到问题。以下是我的来源。
#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 的 bug 还是我怀念用过的 Loki?
提前致谢。
I had encountered a problem while using Loki::Singleton, Loki::SmartPtr, and std::vector under VC express 2008. Following is my source.
#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 ;
}
Compiling and linking has no problem, but after the program finished, an error pops:
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.
It seems some memory are deleted twice, I am quite not sure. Is that a bug of VC or I miss used Loki?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您使用 VC 时,您应该能够在调试模式下运行代码,一步一步(F10、F11)查看代码在哪里中断。
无论如何,查看 Loki 单例代码,似乎错误来自SingletonHolder::DestroySingleton() 中的断言:
该函数似乎由 LifetimePolicy(此处为 DefaultLifetime)调用,如以下代码所示:
我不确定为什么它被调用两次,但我猜指向单例的指针首先被销毁(指针,而不是实例)在 SingletonHolder 实例销毁上,然后 LifetimePolicy 尝试调用它的 DestroySingleton() 函数......
但我可能是错的,你必须检查这一点。
As you're using VC, you should be able to run your code in debug mode, step by stp (F10,F11) to see where it breaks.
Anyway, looking at the Loki singleton code, it seems that the error comes from the assert in SingletonHolder::DestroySingleton() :
That function seems to be called by the LifetimePolicy (here DefaultLifetime) as this code suggests :
I'm not sure why it is called twice, but I guess the pointer to the singleton is first destroyed (the pointer, not the instance) on the SingletonHolder instance destruction and then the LifetimePolicy try to call it's DestroySingleton() function...
But I might be wrong, you'll have to check that.
IMR,您不能在 stl 容器中使用某些智能指针,这正是发生的问题。 如果内存有用,则与 stl 容器如何复制不符合智能指针预期使用方式的值有关。
IMR, you can't use certain smart pointers in stl containers, and this is the exact problem that occurs. If memory serves, it has to do with how the stl containers copy the values not conforming to how smart pointers expect to be used.
Loki的智能指针对于STL容器没有任何问题。 如果您以这种方式重写此示例:
它可以正常工作,没有任何问题。
这里发生的情况是,同一个类不应该同时用作
Loki::Singleton
和Loki::SmartPtr
- 它是直接创建和销毁的在Loki::Singleton
中,但为Loki::SmartPtr
维护引用计数。但是如果您使用
Loki::SmartPtr
作为Loki::Singleton
的参数,它就可以工作! 您必须对代码进行的唯一修改是专门化Loki::CreateUsingNew
类,以创建使用新创建的Foo 初始化的
Loki::SmartPtr
:Loki's smart pointers have no problems with STL containers. If you re-write this sample this way:
it works without any problems.
What is happening here, is that same class isn't supposed be used as
Loki::Singleton
and inLoki::SmartPtr
at the same time - it's created and destroyed directly inLoki::Singleton
, but reference count is maintained forLoki::SmartPtr
.But if you use
Loki::SmartPtr<Foo>
as parameter ofLoki::Singleton
it works! The only modification you have to make to your code is a specialization ofLoki::CreateUsingNew
class to createLoki::SmartPtr<Foo>
initialized with freshly createdFoo
: