在 C 中初始化数组

Initializing arrays in C

下面的 C 程序创建了一个包含固定数量元素的数组。即使我们再分配三个超过最大数组元素数量的值也能正常工作。

#include <stdio.h>

int main(){

//declares a fixed sized array
int balance[5];

//initializing
balance[0] = 1;
balance[1] = 2;
balance[2] = 3;
balance[3] = 4;
balance[4] = 5;
//three more
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;


printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[7]);

//and it works fine!

return 0;
}

但是当我们尝试分配三个以上的元素时它会抛出异常

#include <stdio.h>

int main(){

//declares a fixed sized array
int balance[5];

//initializing
balance[0] = 1;
balance[1] = 2;
balance[2] = 3;
balance[3] = 4;
balance[4] = 5;
//three more
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
//one more again
balance[8] = 9;


printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[7]);
printf("%d \n", balance[8]);

//throws an exception!

return 0;
}

但是在使用整数文字声明和初始化数组后,我们可以插入更多元素而不会出错。

#include <stdio.h>

int main(){

//declares and initialize a fixed sized array
int balance[5] = {1,2,3,4,5};

//let's add few more
balance[5] = 6;
balance[6] = 7;

//and even more
balance[7] = 8;
balance[8] = 9;
balance[9] = 10;

printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[6]);
printf("%d \n", balance[7]);
printf("%d \n", balance[8]);
printf("%d \n", balance[9]);

//and it works fine!

return 0;
}

C语言出现这种行为的原因是什么?

您正在访问未分配的内存,这将调用未定义的行为。什么事情都可能发生。这些都是越界访问

balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
balance[8] = 9;

数组越界访问导致未定义的行为。您的数组可以容纳 5 个整数元素,因此您的数组的有效索引是 04 除此以外的任何数组都是越界访问。

当您尝试越界访问数组时,您的代码调用了未定义行为,这是不安全的内存,因此结果是未定义的。

我想给出一个更通用的答案。这里的每个人都得到了正确的答案,但我想解释为什么并且解释得更冗长一些。 假设您有一个包含 3 个案例的字符数组。

  char tab[3];

在内存方面,我们得到的是分配了3例数据。因为它是一个数组,所以它在你的记忆中是对齐的。让我们初始化该数组:

tab[0] = 'A';
tab[1] = 'B';
tab[2] = 'C';

在你的记忆中,它看起来像这样:

现在,如果你写 tab[6] 会发生什么?因为它是 C,你可以清楚地做到这一点,没有任何问题。 (没有electric-fence ;))

在这种情况下,tab[6] 尚未分配给您的程序。从现在开始你可以有任何场景:

  • 也许这个数据对系统来说是关键的,你的程序将无法访问那个内存(即分段错误)
  • 也许您的程序在某处有另一个数组,您可能会幸运地从那里得到一些东西。
  • (其他比这更糟糕的事情)
  • ???

基本上,当您引发 越界错误 时,您会导致意外行为。你应该做的是始终注意那些错误,它们可能是你心爱的应用程序的致命杀手。