一个有趣的C语言例子
先看下这个例子的代码:
1 | void init_array() { |
代码中init_array和print_array各自有一个长度为10的局部数组arr。init_array把它内部的arr初始化成0~9,print_array把它内部的arr遍历输出到控制台,然后在main函数中对它们进行调用。
print_array执行后输出到控制台:
1 | 0 1 2 3 4 5 6 7 8 9 |
结果有点让人疑惑,似乎这两个函数有着某种关系。
现在取消对init_array的调用,再看下结果:
1 | 177988 32765 5497827 21857 2157688 32518 9257904 21857 0 0 |
这次输出了随机值,因为C/C++并不会初始化内存中的值,这些值都是上一次使用这些内存的程序留下的。
对比两次结果发现init_array确实对print_array中的数组arr产生了影响。init_array和print_array中的arr看起来都各自独立,为什么会出现这种情况?
来看下这两个函数各自在返回前的栈帧结构:

可以发现它们的栈帧结构和大小完全一样。init_array执行完之后它的栈帧被销毁,但是原来的值还在内存中。当print_array执行时继续给它分配了同一块内存且栈帧结构也一样,这样就把init_array在内存中遗留的数据拿到了。
我们对代码稍作修改,让这两个函数都把各自arr在内存中的地址输出到控制台:
1 | void init_array() { |
控制台结果:
1 | 0x7ffd2aaf3ff0 |
结果再一次印证了这两个arr被放到了是同一块栈内存中。所以print_array输出了原先在init_array中arr的值。