我在 Ubuntu 12.10 x86_64 上使用 gcc 版本 4.7.2。
首先是我终端上数据类型的大小:
sizeof(char) = 1
sizeof(short) = 2 sizeof(int) = 4
sizeof(long) = 8 sizeof(long long) = 8
sizeof(float) = 4 sizeof(double) = 8
sizeof(long double) = 16
现在请看一下这段代码片段:
int main(void)
{
char c = 'a';
printf("&c = %p\n", &c);
return 0;
}
如果我没记错的话,我们无法预测c
. 但是每次这个程序都会给出一些以 . 结尾的随机十六进制地址f
。所以下一个可用位置将是一些以 . 结尾的十六进制值0
。在其他数据类型的情况下,我也观察到了这种模式。对于 int 值,地址是一些以 . 结尾的十六进制值c
。对于双精度,它是一些随机的十六进制值8
,以此类推。
所以我在这里有两个问题。
1) 谁在管理这种内存分配?它是 gcc 还是 C 标准?
2)不管是谁,为什么会这样?为什么变量以这样一种方式存储,即下一个可用内存位置从以 结尾的十六进制值开始0
?有什么具体的好处吗?
现在请看一下这段代码片段:
int main(void)
{
double a = 10.2;
int b = 20;
char c = 30;
short d = 40;
printf("&a = %p\n", &a);
printf("&b = %p\n", &b);
printf("&c = %p\n", &c);
printf("&d = %p\n", &d);
return 0;
}
现在在这里我观察到的对我来说是全新的。我认为变量会按照它们声明的顺序存储。但不是!事实并非如此。这是随机运行之一的示例输出:
&a = 0x7fff8686a698
&b = 0x7fff8686a694
&c = 0x7fff8686a691
&d = 0x7fff8686a692
似乎变量按其大小的递增顺序排序,然后以相同的排序顺序存储,但保持观察 1。即最后一个变量(最大的变量)以这样一种方式存储,即下一个可用内存位置是以 .结尾的十六进制值0
。
以下是我的问题:
3)谁是幕后黑手?它是 gcc 还是 C 标准?
4)为什么要浪费时间先对变量进行排序然后分配内存,而不是在“先到先得”的基础上直接分配内存?这种排序然后分配内存有什么特别的好处吗?
现在请看一下这段代码片段:
int main(void)
{
char array1[] = {1, 2};
int array2[] = {1, 2, 3};
printf("&array1[0] = %p\n", &array1[0]);
printf("&array1[1] = %p\n\n", &array1[1]);
printf("&array2[0] = %p\n", &array2[0]);
printf("&array2[1] = %p\n", &array2[1]);
printf("&array2[2] = %p\n", &array2[2]);
return 0;
}
现在这对我来说也很震惊。我观察到的是,如果数组总是存储在某个以“0”结尾的随机十六进制值中,elements of an array >= 2
并且如果elements < 2
它在观察 1 之后获得内存位置。
所以这是我的问题:
5) 谁在这个以 thing 结尾的随机十六进制值存储数组的背后0
?它是 gcc 还是 C 标准?
6)现在为什么要浪费内存?我的意思是array2
可以在之后立即存储array1
(因此array2
内存位置会以 结尾2
)。但不是将其array2
存储在下一个十六进制值处,0
从而在其间留下 14 个内存位置。有什么具体的好处吗?