【发布时间】:2019-03-26 03:36:32
【问题描述】:
我有两个 AWS lightail vps 盒子,我正在两个 vps 上尝试以下简单的 C 程序来测试局部变量的地址。
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int value = 5;
char buffer_one[8], buffer_two[8];
strcpy(buffer_one, "one");
strcpy(buffer_two, "two");
printf("buffer_one is at %p\n", buffer_one);
printf("buffer_two is at %p\n", buffer_two);
return 0;
}
在盒子 A(运行 ubuntu 14.04)上,它会产生如下内容:
buffer_one is at 0x7ffd1fe3d5a0
buffer_two is at 0x7ffd1fe3d5b0
在框 B 上(运行 Centos 7.5,如下:
buffer_one is at 0x7fffa53678a0
buffer_two is at 0x7fffa5367890
我很惊讶,因为这两个变量都在主函数中,这使得它们成为局部变量,因此它们应该在运行时存储在程序地址空间的“堆栈”中。如果是这样,第一个变量(buffer_one)应该在一个比第二个变量(buffer_two)“更高”的地址。 B确实是这样,但是为什么A是相反的……?
【问题讨论】:
-
副本要求同一程序中不同功能的不同布局,但答案与理解为什么在不同甚至相同的编译器上可能重新排序有关。
-
好的编译器不会盲目地读取声明并按照对象在程序中出现的顺序在堆栈上分配空间。优秀的编译器会阅读所有源代码并寻求最佳代码和安排。这可能包括按大小对对象进行分组以最小化对齐所需的填充,并且可能包括在不同的时间为不同的对象使用相同的空间。
标签: c memory-address