静态分配的数组如何在 C 的内存中布局?
How are statically allocated arrays laid out in memory in C?
我在玩弄指针,试图根据局部变量在 C 程序中的典型堆叠方式,使用指向另一个变量的指针来操纵一个变量的值。
int i = 30;
int arr[4];
printf("%d\n", *(arr - 5)); // 30
int arr[4];
int i = 30;
printf("%d\n", *(arr - 5)); // also 30
我认为后者应该为 *(arr + 5)
打印 30,因为这就是我认为局部变量被压入堆栈的方式,但变量似乎以相同的方式在内存中布局。我想了解这里发生了什么。另外,我假设这是 system/compiler 依赖的。
简短回答:内存布局(不同变量之间)取决于编译器,并且取决于实现。
长答案:编译器可以决定如何为变量分配内存。虽然大多数编译器会按顺序分配内存,但并不能保证。特别是,尤其是在优化的时候,编译器可能会去掉不用的变量,或者直接放到寄存器中。
另一个因素是对齐。编译器可能决定重新排序变量以减少变量之间的填充。
访问超出数组边界的值具有未定义的效果。在你的例子中,你得到的值是随机的,恰好是 30。
我在玩弄指针,试图根据局部变量在 C 程序中的典型堆叠方式,使用指向另一个变量的指针来操纵一个变量的值。
int i = 30;
int arr[4];
printf("%d\n", *(arr - 5)); // 30
int arr[4];
int i = 30;
printf("%d\n", *(arr - 5)); // also 30
我认为后者应该为 *(arr + 5)
打印 30,因为这就是我认为局部变量被压入堆栈的方式,但变量似乎以相同的方式在内存中布局。我想了解这里发生了什么。另外,我假设这是 system/compiler 依赖的。
简短回答:内存布局(不同变量之间)取决于编译器,并且取决于实现。
长答案:编译器可以决定如何为变量分配内存。虽然大多数编译器会按顺序分配内存,但并不能保证。特别是,尤其是在优化的时候,编译器可能会去掉不用的变量,或者直接放到寄存器中。
另一个因素是对齐。编译器可能决定重新排序变量以减少变量之间的填充。
访问超出数组边界的值具有未定义的效果。在你的例子中,你得到的值是随机的,恰好是 30。