我使用VS2015,并且在使用std :: thread时遇到了一个非常奇怪的问题。std :: thread在使用参数创建时抛出访问冲突异常?
void Klass::myfunc(int a, int b) { std::cout << a << ' ' << b << std::endl; }
// ...
auto t = std::thread(&Klass::myfunc, this, 100, 200); <- runtime error after called
// ...
t.join();
它运作良好,在调试模式,而是抛出一个“访问冲突异常”当我打开来释放模式。
更重要的是,如果我尝试修改 “MYFUNC” 这样的:
void Klass::myfunc() { std::cout << "foo" << std::endl; }
// ...
auto t = std::thread(&Klass::myfunc, this); // everything goes well
// ...
t.join();
一遍效果很好。
我保证“& Klass :: myfunc”和“this”指针不为NULL。当ctor被呼叫时,在几行后有一个“加入”。
我想这可能是某种“未定义的行为”,但我不知道它到底是什么。
调用堆栈是这样的:
000000c83a4ffd40() Unknown
> distributed_word_embedding.exe!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl multiverso::Communicator::*)(void) __ptr64,multiverso::Communicator * __ptr64>,std::default_delete<std::tuple<void (__cdecl multiverso::Communicator::*)(void) __ptr64,multiverso::Communicator * __ptr64> > > >::_Run(std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl multiverso::Communicator::*)(void),multiverso::Communicator *>,std::default_delete<std::tuple<void (__cdecl multiverso::Communicator::*)(void),multiverso::Communicator *> > > > * _Ln) Line 247 C++
distributed_word_embedding.exe!std::_Pad::_Call_func(void * _Data) Line 210 C++
ucrtbase.dll!00007ffabdc7be1d() Unknown
kernel32.dll!00007ffabfae8102() Unknown
ntdll.dll!00007ffac26bc5b4() Unknown
你做线程后会发生什么?你会加入吗? – doctorlove
@doctorlove可能暗示的是,这看起来像一个生命期问题,其中线程超过了Klass实例,因此有一个悬空的指针。通过加入正确的地方,你可以防止这一点。然而,我们无法确定基于所呈现的情况。 – stefaanv
@doctorlove stefaanv嗨,谢谢你的回复。实际上,调试器和日志显示程序在调用std :: thread的ctor后立即停止,并且“join”之后是几行。我认为问题不在于“加入”。而且我在这个问题中还提到,如果我不带任何参数地称呼“myfunc”,那么一切都会顺利。 – Wizmann