描述
- 程序调用到析构函数中的时候,会根据变量的创建顺序执行析构。如果在析构中调用线程,并且线程中使用了其他的对象,一旦其他的对象已经被析构释放,线程在调用该对象的时候会出现意料之外的错误。看一段代码具体分析
code
#include <iostream>
#include <thread>
#include <functional>
#include <unistd.h>
#include <mutex>
using namespace std;
typedef std::function<void()> FUNC;
class MyThread
{
public:
~MyThread()
{
cout << "MyThread" << endl;
if (thread_.joinable()) {
thread_.join();
}
}
void run(FUNC func) {
std::thread tt([func](){
sleep(3);
func();
});
thread_ = std::move(tt);
}
private:
std::thread thread_;
};
class Test
{
public:
~Test(){
cout << "Test" << ":" << &t << endl;
}
void P(){
t += 1;
cout << "Test" << ",value:" << t << ":" << &t << endl;
}
private:
int t{5};
};
int main()
{
MyThread t;
// std::shared_ptr<Test> test = std::make_shared<Test>();
Test* test = new Test();
t.run([=](){
test->P();
});
delete test;
return 0;
}
预期结果
实际结果
Test:0x116f010
MyThread
Test,value:18280481:0x116f010
分析
- 我们在第53行先执行了Test的析构函数,类对象test的指针成为野指针。在之后执行MyThread的析构函数,线程执行任务,但是test对象已变成野指针,调用其成员变量将出现意料之外的错误。