为什么在我没有使用static
的情况下为第二次调用保留数据?
这是代码,输出以及我期望的输出应该是什么。
#include <stdio.h>
void fun(int len)
{
int arr[10];
int i;
for (i = 0; i < len; i++)
arr[i] = (i+1) * 10;
for (i = 0; i < 10; i++)
printf("%d ", arr[i]);
printf("n");
}
int main(void) {
fun(10);
fun(4);
return 0;
}
输出:
10 20 30 40 50 60 70 80 90 100
10 20 30 40 50 60 70 80 90 100
预期输出:
10 20 30 40 50 60 70 80 90 100
10 20 30 40 0 0 0 0 0 0
int arr[10];
在堆栈上声明一个包含 10 个int
元素的数组。其元素未初始化。如果您尝试在不初始化的情况下访问它们,例如 fun(4)
,您可能会看到垃圾值,您可能会碰巧看到旧的内存内容(就像您在此处所做的那样),或者如果内存页属于另一个程序,您可能会因分段错误而使程序崩溃。您甚至可以获得预期的输出!事实上,任何事情都可能发生,因为规范未定义行为。
为了满足您的期望,请以您选择的任何方式初始化数组,例如以下方式之一:
int arr[10] = {};
int arr[10] = {0};
int arr[10];
memset(arr, 0, sizeof(int) * 10);
int arr[10];
for (int i = 0; i < 10; i++) {
arr[i] = 0;
}
等。
请初始化数组。
喜欢这个
void fun(int len)
{
int arr[10] = {0}; //changed
int i;
for (i = 0; i < len; i++)
arr[i] = (i+1) * 10;
for (i = 0; i < 10; i++)
printf("%d ", arr[i]);
printf("n");
}
您通过访问未初始化的内存来调用未定义的行为。结果可能是任何东西,包括您的计算机长腿和逃跑。
在实践中,可能发生的情况是您的函数调用占据堆栈上的同一位置,因为它们之间或内部没有其他调用。arr
变量两次都位于堆栈上的同一位置。第一次初始化比第二次初始化更全面,因此您看不到完全垃圾。这是意料之中的,但肯定从未依赖过。
数组 arr[] 在默认情况下未初始化的堆栈中分配,这些值是上次分配此区域时使用的值,在这种情况下它恰好在 2 个有趣的调用之间分配相同的堆栈区域,并且堆栈区域由第一次调用初始化。