我在C语言中遇到了一个奇怪的现象,我需要有人来解释。我有下面的代码与2个单元素数组作为全局变量。我正在打印每个数组的第一个和第二个元素的内存地址(注意,数组被定义为只有一个元素):
#include <stdio.h>
int a1[1];
int a2[1];
int main(void) {
a1[0] = 100;
a2[0] = 200;
printf("%dn", &a1[0]);
printf("%dn", &a1[1]);
printf("%dn", &a2[0]);
printf("%dn", &a2[1]);
}
输出如下。注意,C在数组a1后面为数组a2分配了一个连续的内存块(因此a1[1]和a2[0]的地址是相同的):
4223424
4223428
4223428
4223432
然而,当我改变数组的名称时,奇迹发生了。我将"zzz"作为前缀添加到两个数组中,如下所示。
#include <stdio.h>
int zzza1[1];
int zzza2[1];
int main(void) {
zzza1[0] = 100;
zzza2[0] = 200;
printf("%dn", &zzza1[0]);
printf("%dn", &zzza1[1]);
printf("%dn", &zzza2[0]);
printf("%dn", &zzza2[1]);
}
运行此代码后,您可以从以下输出中看到,首先为数组zzza2分配了内存,然后为zzza1分配了内存(&a2[1] = &a1[0]):
4223428
4223432
4223424
4223428
我已经在不同的机器上在不同的时间用多个数组大小(2,4,8)测试了上面的代码,并得到了相同的输出,所以这不是巧合。当我将main()中的变量定义为局部变量时,就不会发生这种情况。
似乎C是根据我们提供给数组的名称分配内存的。首先,为什么C每次分配连续块到不同的全局数组?其次,当我添加前缀时,为什么内存分配的顺序发生了变化?
希望这不会让大家感到困惑,因为它有我…提前感谢您的帮助!
首先,为什么C将连续的块分配给不同的全局数组每次?
因为一个连续的块更有效,更容易实现。如果应用程序在不同的内存块上分配全局变量,它至少有以下一个缺点:
- 块间内存浪费。
- 启动时内存分配复杂。
所以工具链试图分配所有的全局变量在一个连续的内存块