为何以下C语言主程序中两个字符指针的取值相同?
问题分析:为何两个指针指向同一地址并输出相同内容
原程序代码
#include <stdio.h> void fun1(char **p1) { char ch1[] = "abc"; *p1 = ch1; } void fun2(char **p2) { char ch2[] = "def"; *p2 = ch2; } int main() { char *p1 = NULL; char *p2 = NULL; fun1(&p1); fun2(&p2); printf("string %s %s", p1, p2); return 0; }
运行输出
string def def
内部运行机制解析
这一现象的核心原因是栈帧复用和局部变量生命周期结束后的非法内存访问:
- 函数
fun1和fun2中的ch1、ch2都是栈上分配的局部数组。这类变量的生命周期仅限于函数执行期间,当函数执行完毕返回时,它们所在的栈帧会被操作系统回收,对应的内存空间被标记为可复用状态。 - 由于
fun1和fun2的函数签名完全一致,栈帧的结构和占用大小完全相同。当程序先调用fun1再调用fun2时,操作系统会直接复用fun1刚释放的栈空间来存放fun2的局部变量ch2,这就导致ch2的内存地址和之前ch1的地址完全重合。 - 在
fun1返回后,main中的p1保存的是已经失效的ch1的地址;随后fun2把ch2的地址(也就是和ch1相同的地址)赋值给p2。此时p1和p2指向同一块栈内存,而这块内存最后被ch2写入了"def",所以printf会输出两次def。
需要注意的是,这种访问已销毁局部变量内存的行为属于C标准定义的未定义行为——在不同编译器、优化级别或运行环境下,可能出现不同的结果(比如崩溃、输出乱码等),当前的输出只是栈帧复用场景下的一种典型表现。
内容的提问来源于stack exchange,提问作者H Kumar
相关产品推荐
相关产品推荐

