[英]C array traversal cause loop on c90 standard (but not on c99)
#include <stdio.h>
int main(void){
double arr[] = { 1.1, 2.2, 3.3, 4.4 };
int i;
for (i=0; i<=4; i++) {
printf("%d\n", i);
arr[i] = 0;
}
return 0;
}
Compiling with gcc(c90) gives an infinite loop(1,2,3,4,1,2,3,4...) while compiling with gcc(c99) produces only (0, 1, 2, 3, 4).使用 gcc(c90) 编译会产生无限循环 (1,2,3,4,1,2,3,4...) 而使用 gcc(c99) 编译只会产生 (0, 1, 2, 3, 4) . What can be attributed to the difference?什么可以归因于差异?
You are writing to an element outside the array (namely when i
is 4).您正在写入数组外的元素(即当i
为 4 时)。
This leads to undefined behavior hence anything could happen.这会导致未定义的行为,因此任何事情都可能发生。
Arr
is declared with 4 values, but you are accessing 5 of it ( i=0; i<=4
). Arr
声明有4 个值,但您正在访问其中的5个( i=0; i<=4
)。 Accessing an array out-of-bounds results in undefined behavior.越界访问数组会导致未定义的行为。
What exactly happens if you do that depends on implementation details of the compiler, linker, and OS - if the compiler has put i
there, you are overwriting i with 0;如果你这样做,究竟会发生什么取决于编译器、链接器和操作系统的实现细节——如果编译器把i
放在那里,你用 0 覆盖 i; if it has put your stack frame there, you will end up with a crash, etc.如果它把你的堆栈框架放在那里,你最终会崩溃,等等。
In loop you are assigning arr[4] = 0
, but array has only 4 elements (arr[0..3]), so you are assigning value to memory outside of array.在循环中,您正在分配arr[4] = 0
,但数组只有 4 个元素 (arr[0..3]),因此您将值分配给数组外的内存。 In this place compiler has placed int i
, because it is declared just after array.编译器在这个地方放置了int i
,因为它是在数组之后声明的。
If you look at the assembly, you'll see that the variable i is stored at the end of the array, right after arr[3].如果查看程序集,您会看到变量 i 存储在数组的末尾,紧跟在 arr[3] 之后。 On my computer, it is not aligned in a way that it is exactly at arr[4] but I'm guessing on yours, the variable i is located exactly at arr[4] and thus you are overwriting it to 0 by going out of bounds in your for loop with the <= instead of <.在我的电脑上,它并没有以恰好在 arr[4] 处的方式对齐,但我猜你的,变量 i 正好位于 arr[4] 处,因此你通过外出将其覆盖为 0在 for 循环中使用 <= 而不是 < 的边界。 This means in the last iteration of your for loop, you are setting i to 0 which keeps the loop going infinitely.这意味着在 for 循环的最后一次迭代中,您将 i 设置为 0,从而使循环无限进行。
000000000040052d <main>:
40052d: 55 push %rbp
40052e: 48 89 e5 mov %rsp,%rbp
400531: 48 83 ec 30 sub $0x30,%rsp
400535: 48 b8 9a 99 99 99 99 movabs $0x3ff199999999999a,%rax
40053c: 99 f1 3f
40053f: 48 89 45 e0 mov %rax,-0x20(%rbp) # move 1.1 into arr[0] at memory address rbp - 0x20
400543: 48 b8 9a 99 99 99 99 movabs $0x400199999999999a,%rax
40054a: 99 01 40
40054d: 48 89 45 e8 mov %rax,-0x18(%rbp) # move 2.2 into arr[1] at memory address rbp - 0x18
400551: 48 b8 66 66 66 66 66 movabs $0x400a666666666666,%rax
400558: 66 0a 40
40055b: 48 89 45 f0 mov %rax,-0x10(%rbp) # move 3.3 into arr[2] at memory address rbp - 0x10
40055f: 48 b8 9a 99 99 99 99 movabs $0x401199999999999a,%rax
400566: 99 11 40
400569: 48 89 45 f8 mov %rax,-0x8(%rbp) # move 4.4 into arr[3] at memory address rbp - 0x8
40056d: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%rbp) # declaring i at memory address rbp-0x24 (notice this is at location arr[4] (kind of))
400574: eb 28 jmp 40059e <main+0x71>
400576: 8b 45 dc mov -0x24(%rbp),%eax
400579: 89 c6 mov %eax,%esi
...
You are trying to access arr[4]
since i
value goes till 4 because of i<=4
.您正在尝试访问arr[4]
,因为i<=4
导致i
值变为i<=4
。 But you have only arr[0],arr[1],arr[2],arr[3]
in the array.但是数组中只有arr[0],arr[1],arr[2],arr[3]
。 You have change the condition in the for
loop to i<4
.您已将for
循环中的条件更改为i<4
。
#include <stdio.h>
int main(void){
double arr[] = { 1.1, 2.2, 3.3, 4.4 };
int i;
for (i=0; i<4; i++) { // Since you have only 4 values in the array
printf("%d\n", i);
arr[i] = 0;
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.