Я использую VS2015 и сталкиваюсь с чрезвычайно странной проблемой при использовании std :: thread.std :: thread throws Исключение нарушения прав доступа при создании с помощью аргументов?
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» и «это» указатели не являются 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
Вероятно, это намек на то, что это похоже на пожизненную проблему, где поток выдает экземпляр Klass и, таким образом, обманывает этот указатель. Присоединившись в нужном месте, вы можете предотвратить это. Однако мы не можем быть уверены, основываясь на представленном контенсе. – stefaanv
@doctorlove stefaanv привет, спасибо за ваш ответ. На самом деле отладчик и журнал показывают, что программа выключена сразу после вызова ctor std :: thread, а «join» - несколько строк после. Я думаю, что проблема не в том, чтобы «присоединиться».И я также упомянул в вопросе, что если я называю «myfunc» без аргументов, все будет хорошо. – Wizmann