我有一个线程本地单例类,看起来有点像这样:
// UserActionManager.hh
class UserActionManager
{
public:
static UserActionManager* GetUserActionManager();
~UserActionManager() { std::cout << "UAM destructor called.\n"; }
static thread_local std::unique_ptr<UserActionManager> theInstance;
};
// UserActionManager.cc
thread_local std::unique_ptr<UserActionManager> UserActionManager::theSafeInstance = nullptr;
UserActionManager*
UserActionManager::
GetUserActionManager()
{
if (nullptr == theInstance)
{
theInstance.reset(new UserActionManager());
std::cout << "theInstance = " << theInstance.get() << "\n";
}
return theInstance.get();
}
我需要为实例使用动态分配,因为必须在我的程序中完成其他步骤后创建UserActionManager。
当我运行程序时,它可以正常运行,直到程序退出。我收到这样的错误:
simple(57724,0x10b647000) malloc: *** error for object 0x7fc64ce79460: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
simple(57724,0x10d64d000) malloc: *** error for object 0x7fc64ce7b140: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
simple(57724,0x10c64a000) malloc: *** error for object 0x7fc64ce7b8e0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
*** Break *** illegal instruction
*** Break *** illegal instruction
*** Break *** illegal instruction
如果我在lldb中运行程序,我收到此消息,告诉我在我的thread_local UserActionManager实例的默认删除调用中发生了崩溃。
// lldb输出
Process 57201 stopped
* thread #2: tid = 0x8d5d1, 0x0000000105a2eed7 libGex.dylib`std::default_delete<gex::ua::UserActionManager>::operator()(gex::ua::UserActionManager*) const + 27, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x0000000105a2eed7 libGex.dylib`std::default_delete<gex::ua::UserActionManager>::operator()(gex::ua::UserActionManager*) const + 27
libGex.dylib`std::default_delete<gex::ua::UserActionManager>::operator()(gex::ua::UserActionManager*) const + 27:
-> 0x105a2eed7: movq (%rax), %rax
0x105a2eeda: addq $0x48, %rax
0x105a2eede: movq (%rax), %rax
0x105a2eee1: movq -0x10(%rbp), %rdx
但是,如果你查看线程本地实例的代码打印的指针和未被分配的释放指针,它们就不一样了:
//由GetUserActionManager()打印的指针:
0x7fc650948300
0x7fc64a4de670
0x7fc650b33480
0x7fc650c19f90
//导致崩溃的指针:
0x7fc64ce79460
0x7fc64ce7b140
0x7fc64ce7b8e0
这里发生了什么?我过去使用过这段代码没有问题。现在我在MacOSX和c ++ 14上使用g ++ 4.9.1并且崩溃了。永远不会调用UserActionManager的析构函数,默认删除尝试释放的指针与它应该具有的指针不同。我已经使用了grepped代码,这只是在创建它的静态方法中引用了Instance,所以我不认为这是来自其他地方的副作用。如果我为实例使用原始指针,代码工作正常。
有关如何解决此问题的任何建议?谢谢!
编辑:
我刚刚发现了这个:
Why global or static object can lead to crash when program exit?
UserActionManager现在是库的一部分,程序&#34;简单&#34;是链接到它。以前(当这个工作时)我将代码编译为一个整体。这会导致问题吗?&#34;