C++ 单例模板类使我的程序崩溃
Posted
技术标签:
【中文标题】C++ 单例模板类使我的程序崩溃【英文标题】:C++ singleton template class crashes my program 【发布时间】:2019-11-27 04:32:29 【问题描述】:我创建了一个单例模式作为模板类。
template <typename T>
class TemplateSingleton
protected:
TemplateSingleton()
virtual ~TemplateSingleton()
public:
static T * GetInstance()
if (m_pInstance == NULL)
m_pInstance = new T;
return m_pInstance;
;
static void FreeInstance()
if (m_pInstance != NULL)
delete m_pInstance;
m_pInstance = NULL;
;
private:
static T * m_pInstance;
;
template <typename T> T * TemplateSingleton<T>::m_pInstance = NULL;
并使用继承自子类。 这个类可以通过继承模板作为单例类使用,如果不继承,也可以作为泛型类使用。
#define MAX_COUNT 8
class CDataHandler : public TemplateSingleton<CDataHandler>
public:
CDataHandler();
~CDataHandler();
...
private:
CDataObj m_clDataObj[MAX_COUNT]; // CDataObj *m_clDataObj ?
DWORD m_dwDataObjCount;
...
;
class CDataObj
public:
CDataObj();
~CDataObj();
...
private:
...
;
上面的代码是在一个DLL中,程序被实现为只调用CDataHandler的实例构造函数。 我的程序崩溃并退出。
顺便说一句,如果我将 CDataObj 成员变量从数组更改为指针,它工作正常。 (本例在CDataHandler的构造函数中新建,在析构函数中删除。)
这段代码有问题吗?
加法) CDataHandler 的构造函数和析构函数代码:)
CDataHandler::CDataHandler()
: m_dwDataObjCount(0)
//, m_clDataObj(NULL)
// Do nothing
// m_clDataObj = new CDataObj[MAX_COUNT];
CDataHandler::~CDataHandler()
//if (m_clDataObj != NULL)
for (int i = 0; i < MAX_COUNT; i++)
m_clDataObj[i].Close();
// delete[] m_clDataObj;
// m_clDataObj = NULL;
【问题讨论】:
你是如何实现 CDataHandler ctor 和 dtors 的? 崩溃的原因在于您决定不向我们展示的代码。 @Arun 添加了 CDataHandler 的构造函数和析构函数源代码 @SidS 上面的代码有语法错误吗?如果是这样,应该在其他地方考虑这个问题...... 【参考方案1】:不确定是什么导致您的程序崩溃,但您发布的代码中存在两个潜在问题。
首先,您不知道m_pInstance
何时会被初始化为NULL
。如果在静态数据初始化期间调用GetInstance()
,m_pInstance
可能尚未初始化为NULL
,因此GetInstance()
将返回一些无效指针。查找“静态数据初始化命令fiasko”之类的,这方面的信息很多。
为避免这种情况,您可以使用局部静态变量,如下所示:
T* GetInstance()
static T* t = new T;
return t;
其次,您为单身人士使用模板。没关系,但您必须注意:如果类的定义可用于多个编译单元,则这些编译单元中的每一个都将实例化它们自己的单例,根据您来自哪个编译单元,为您留下多个不同的实例访问它们。
为了解决这个问题,您可以在 DLL 中使用 extern template
为某个 T
告诉其他人他们不应该实例化此模板特化,然后将显式模板实例化编译到 DLL 中,以便为每个人提供实现。
【讨论】:
感谢您的回答。经过几天的调试,似乎不是模板单例。发现容错堆(FTH)相关的日志写入DebugView,在初始化FTH列表的时候就可以了。以上是关于C++ 单例模板类使我的程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
我想从 C++ 非托管代码调用 C# 委托。无参数委托工作正常,但有参数委托使我的程序崩溃
为啥 ntdll.dll 会使我的 c++ 可执行文件崩溃?
为啥我的班级用错误代码 138 使我的 OCUnit 测试用例崩溃?