线程t1将局部变量v的指针传给t2后,t1写其他变量是否会改变t2观测到的v的状态?
自动局部变量跨线程传递后,其他变量写入是否会影响观测状态?
首先明确前提:这里的“传递给线程t2”必然是传递指针/引用——如果是传值,t2拿到的是v的独立副本,t1对任何变量的写入都不可能影响这个副本,因此问题的核心场景是t2持有指向t1栈上自动变量v的指针/引用。
场景1:t1仍未退出包含v的函数(v的栈帧仍有效)
- 栈内存中的变量是连续分配的,若t1对同栈帧内的其他变量执行越界写入,可能直接覆盖v所在的内存区域。比如t1中有数组
int arr[2];和自动变量int v = 10;,栈布局可能是arr在前、v在后,当t1执行arr[3] = 20;(越界写操作),这个写入的内存地址刚好对应v的地址,那么t2通过指针访问v时,看到的数值就会变成20。 - 这种情况属于内存越界的未定义行为,但在实际的栈布局逻辑下完全可能发生,编译器不会对这类越界操作做防护。
场景2:t1已退出包含v的函数(v的栈帧已被回收)
- 自动变量的生命周期与所在栈帧绑定,当t1退出包含v的函数后,原来v占用的栈内存会被后续的函数调用复用。此时t1对新的自动变量(即v以外的变量)执行写入,本质是写入到原来v的内存地址上——因为栈空间是重复利用的,新变量可能刚好分配在v曾经的位置。
- 比如t1退出函数后,又调用了
void func() { int x = 30; },x的栈地址刚好和之前v的地址一致,t1对x的写入会覆盖该地址的内容,t2此时访问v的指针,看到的就是30,而非v原来的值。 - 这是典型的悬垂指针未定义行为,实际运行中这类栈复用导致的覆盖非常常见。
总结
只有当t2持有指向t1栈上v的指针/引用时,t1对其他变量的写入才有可能改变t2观测到的v的状态——本质是内存越界或栈帧复用导致v所在内存被意外覆盖。如果是传值传递,t2拿到的是独立副本,无论t1做什么都不会影响。
内容的提问来源于stack exchange,提问作者Sibulele
相关产品推荐
相关产品推荐

