简体   繁体   English

C 数组遍历导致 c90 标准上的循环(但不在 c99 上)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM