数组在 C 中的函数调用之间保留数据



为什么在我没有使用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 个有趣的调用之间分配相同的堆栈区域,并且堆栈区域由第一次调用初始化。

最新更新