3

我有这个 C 代码片段

int numbers[4]={1};

numbers[0]=1; numbers[1]=2; numbers[3]=3; numbers[10]=4;
printf("numbers: %d %d %d %d %d %d\n",numbers[0],numbers[1],numbers[3],numbers[6],numbers[10],  numbers[5]) ;

此片段的输出产生:

    numbers: 1 2 3 963180397 4 0

好吧,我有几个问题

  1. 不会设置 numbers[10] 给出错误,因为数组的大小仅为 4,如果不是那么为什么(因为它没有给出任何错误)

  2. 为什么打印 numbers[6] 给出垃圾值,而 numbers[5] 给出 0 值?它不应该也是一个垃圾值。

  3. 设置 numbers[10] 有什么影响我知道它不会增加数组的大小但是它会做什么呢?

提前致谢 。PS我用GCC编译代码!!

4

3 回答 3

2
  1. 这不会产生错误,您的数组是在堆栈上声明的,因此 number[10] 所做的是写入地址编号 + (10*sizeof int) 并覆盖任何可能存在的内容。
  2. 正如 Xymotech 所说,0 可能与 963180397 一样多。打印 numbers[6] 将打印存储在地址 numbers + (6*sizeof int) 的内容,因此这取决于您的程序的编译方式,如果您之前声明了局部变量后面的数字等
  3. 见答案 1。

你可以做的是:

int empty[100];
int numbers[4]={1};
int empty2[100];

memset(empty, 0xCC, sizeof empty);
memset(empty2, 0xDD, sizeof empty2);

numbers[0]=1;numbers[1]=2;numbers[3]=3;numbers[10]=4;
printf("numbers: %d %d %d %d %d %d\n",numbers[0],numbers[1],numbers[3],numbers[6],numbers[10],  numbers[5]) ;

现在您可以了解在访问 numbers 数组时要覆盖的内容

于 2012-12-07T22:38:42.163 回答
1

要回答您的问题:

  1. 不必要。如果您静态声明数组,编译器可以将内存保留在更大的块中,或者您可能只是覆盖了堆栈上数组之后的任何其他内容。
  2. 这取决于编译器并且属于“未定义的行为”。
  3. 您将 (numbers + 10) 设置为等号后面的值。
于 2012-12-07T22:38:32.160 回答
0

它不会导致任何错误,因为它已衰减为指针算术。

当你写的时候numbers[10],它只是numbers + 10 * sizeof(numbers),这是相当正确的。

访问您不打算访问的内存(未为您分配)是未定义的行为,因此您访问的每个越界索引都是垃圾,包括0.

正如您所说,访问大于 4 的索引不会增加数组的大小,此外,它也不会做任何事情。

于 2012-12-07T22:44:01.070 回答