C中的数组大小和地址

use*_*466 2 c memory

当我编译下面的代码时,它显示y和数组的开头相隔60个单位.但根据我的计算,它应该是4*10(对于数组)+ 4(对于k)+ 4(对于y)= 48.此外,数组[12] = 17被分配给元素12,因为没有元素12,实现应该转到y并用17覆盖y.然而控制台打印y = 10而不是...我真的很困惑...请帮忙!

 #include <stdio.h>

 int main(void) {
    int x = 42;
    int y = 10;
    int k = 10;
    int array[10];

    array[12] = 17;
    printf("array starts at %d\n", &array[0]);
    printf("x has the value %d\n", x);
    printf("x is stored in location %d\n", &x);

    printf("y has the value %d\n", y);
    printf("y is stored in location %d\n", &y);
 }
Run Code Online (Sandbox Code Playgroud)

Ed *_* S. 7

这称为未定义行为(在10元素数组中写入数组[12]),因此根据定义,您无法知道它该做什么.在C中没有运行时检查,所以你可以写到你想要的任何地方(好吧,为了这个例子),你不知道究竟会发生什么.


ale*_*gle 5

当我编译这段代码(OSX上的gcc)时,它会告诉我y和你array的相距8个字节.这正是我所期待的......当地人正在这样布局:

int x = 42;
int y = 10;
int k = 10;
int array[10];

0                   1                   2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3...etc.
\__,__/ \__,__/ \__,__/ \__,__/ \__,__/ \__,__/
   x       y       k      [0]     [1]     [2]
                          array
Run Code Online (Sandbox Code Playgroud)

数字是堆栈框架底部的偏移量.因此x填充底部4个字节,"y"堆叠在其上,依此类推.该数组长40个字节,位于最顶层.

&y是起始地址y,它是堆栈帧底部的+4个字节.&array[0]是数组起始地址,它是堆栈帧底部的+12字节.

顺便说一句,你应该把你的地址格式化为'unsigned' - %u.没有它,大地址可能会出现负数.

array[12]超出所有这一切的结束,所以你不应该期望它会影响y.如果你想玩未定义的行为,那么array[-2]可能相当于y.为了让它像这样工作,我不得不编译优化 - 你的里程可能会有所不同:)

  • 这些变量的布局不是由语言定义的,因此任何实现都是*可能*.特别是,你的程序实际上并没有使用变量k,我发现说服编译器将它包含在堆栈中非常棘手. (3认同)