请问把局部栈对象的地址作为线程函数的参数,子线程对该地址继续访问是否不安全?

发布于 2022-09-11 23:32:36 字数 660 浏览 38 评论 0

如下所示代码:
`

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,为什么还是没有出错呢?这是为什么呢?我的理解哪里有问题呢?谢谢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尛丟丟 2022-09-18 23:32:36

未定义行为,什么都可能发生

这当然包括程序执行出现你期望的结果(不管你期望的结果是正常执行还是崩溃),或者不是你期望的结果。

================================

闯红灯不安全,但是并不是闯了了红灯就一定出车祸。好多人闯了红灯,啥事没有。

孤独难免 2022-09-18 23:32:36

只要 data 指向的栈地址范围,即内存范围,没有被覆写,你就看不到出错。

该地址属于线程栈,线程结束之后,地址会被回收,被覆写随时可能会发生,就是随时可能出错。

要覆写它的地址,可以这样试一下

void Thread::start()
{
    ...
    {
        ThreadData data(&tid_,threadName_,func_);     
        if(pthread_create(&pid_, nullptr,threadStart,&data))
        ...
    }
    ThreadData data2(&tid_,threadName_, NULL);     
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文