首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Loki::Singleton,Loki::SmartPtr和std::向量的奇怪记忆问题

Loki::Singleton,Loki::SmartPtr和std::向量的奇怪记忆问题
EN

Stack Overflow用户
提问于 2009-07-07 19:22:58
回答 3查看 840关注 0票数 0

2008年在VC快递下,我在使用Loki::SingletonLoki::SmartPtr,和std::时遇到了一个问题。以下是我的消息来源。

代码语言:javascript
复制
#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 ;
}

编译和链接没有问题,但是在程序完成后,会弹出一个错误:

代码语言:javascript
复制
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?

提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-07-07 19:40:16

当您使用VC时,您应该能够以调试模式运行您的代码,分步运行stp (F10,F11)来查看代码的中断位置。

无论如何,查看Loki单例编码,似乎错误来自SingletonHolder::DestroySingleton()中的断言:

代码语言:javascript
复制
 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)调用的,如下代码所示:

代码语言:javascript
复制
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()函数.

但我可能错了,你得检查一下。

票数 1
EN

Stack Overflow用户

发布于 2009-07-07 19:55:19

IMR,您不能在stl容器中使用某些智能指针,而这正是发生的问题。如果内存可用,则与stl容器如何复制不符合智能指针预期使用方式的值有关。

票数 1
EN

Stack Overflow用户

发布于 2021-09-02 07:43:48

Loki的智能指针在STL容器中没有问题。如果您以这样的方式重写此示例:

代码语言:javascript
复制
#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::SingletonLoki::SmartPtr使用--它是在Loki::Singleton中直接创建和销毁的,但是Loki::SmartPtr的引用计数是被维护的。

但是,如果您使用Loki::SmartPtr<Foo>作为Loki::Singleton的参数,它可以工作!您必须对代码进行的唯一修改是对Loki::CreateUsingNew类进行专门化,以创建使用新创建的Foo初始化的Loki::SmartPtr<Foo>

代码语言:javascript
复制
#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 ;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1094276

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档