想象一下,我启动了一个运行对象成员函数的std::thread
。如果该对象在我创建线程的main函数中超出范围会发生什么?
class ThreadClass {
public:
ThreadClass(int i) : _a(i) {
}
void foo() {
sleep(10);
std::cout << "Is it safe here? " << _a << std::endl;
}
int _a;
};
int main() {
{
ThreadClass obj(3);
std::thread t(&ThreadClass::foo, &obj);
t.detach();
}
// Here obj goes out of scope
// What about thread?
sleep(20);
return 0;
}
这是一个未定义的行为吗?
答案 0 :(得分:5)
不,该代码不安全。 thread
拥有对象的非拥有引用(通过指针&obj
的副本)。一旦对象超出范围,那就是悬空参考。
答案 1 :(得分:3)
是的,这是未定义的行为。更具体地说,您将最终遇到分段错误,因为该线程正在尝试访问不再存在的某个对象。所以这就是我的建议:
obj
不会超出范围的地方(可能是全局的)。new
创建对象,并使用std::shared_ptr
将指针传递给线程。 (在这种情况下,您必须确保线程调用delete
操作,以避免内存泄漏。