一个有趣的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
的值。