我使用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