如下所示代码:
`
void* threadStart(void *args)
{
auto data = static_cast<ThreadData*>(args);
data->func_();
.....
}
void Thread::start()
{
......
ThreadData data(&tid_,threadName_,func_);
if(pthread_create(&pid_, nullptr,threadStart,&data))
{
...
}
else
...
}`
代码中的data是一个栈对象,然后将&data作为参数传入pthread_create函数中,在线程函数threadStart中又会使用data,主线程和子线程的data应当是同一个,打印出来的地址也是相同的。
我的理解是,在start函数执行结束,data这个栈对象就会析构,此时线程函数又接着去对栈对象的地址进行访问,那么这样写应该是不安全的吧?但是也没看到程序报错,我特意在线程函数前进行了sleep,确保start函数中的data栈对象析构了才开始在线程函数中访问&data,为什么还是没有出错呢?这是为什么呢?我的理解哪里有问题呢?谢谢
2 个回答
只要 data
指向的栈地址范围,即内存范围,没有被覆写,你就看不到出错。
该地址属于线程栈,线程结束之后,地址会被回收,被覆写随时可能会发生,就是随时可能出错。
要覆写它的地址,可以这样试一下
void Thread::start()
{
...
{
ThreadData data(&tid_,threadName_,func_);
if(pthread_create(&pid_, nullptr,threadStart,&data))
...
}
ThreadData data2(&tid_,threadName_, NULL);
...
}
*未定义行为,什么都可能发生*
这当然包括程序执行出现你期望的结果(不管你期望的结果是正常执行还是崩溃),或者不是你期望的结果。
闯红灯不安全,但是并不是闯了了红灯就一定出车祸。好多人闯了红灯,啥事没有。
撰写答案