变量如何在C中存储在内存中,根据它们的类型

时间:2018-03-08 21:22:02

标签: c memory

所以我试图理解C如何将我的变量存储在内存中,并且在我遇到这个问题之前我一直做得很好:

我编写了以下简单的程序,它告诉我变量逐个存储的位置,这样我就可以知道类型之间的区别,但我无法建立任何链接,这个数字在我相信的同时看起来如此随意它与类型有关。那么,任何线索为什么角色总是得到较低的内存地址,即使它们是最后声明的呢?

int main ()
{
    int integer1 = 6;
    int integer2 = 2;
    int integer3 = 3;
    char character1 = 'C';
    char character2 = 'B';
    char character3 = 'D';
    char string1[4] = "Hi!";
    char string2[4] = ":D";
    char string3[4] = "ack!";

    printf ("integer1 : %d, at %p\n", integer1, &integer1);
    printf ("integer2 : %d, at %p\n", integer2, &integer2);
    printf ("integer3 : %d, at %p\n", integer3, &integer3);
    printf ("character1 : %c, at %p\n", character1, &character1);
    printf ("character2 : %c, at %p\n", character2, &character2);
    printf ("character3 : %c, at %p\n", character3, &character3);
    printf ("string1 : %s, at %p\n", string1, string1);
    printf ("string2 : %s, at %p\n", string2, string2);
    printf ("string3 : %s, at %p\n", string3, string3);
}

输出:

integer1 : 6, at 0x7ffe40915b40
integer2 : 2, at 0x7ffe40915b44
integer3 : 3, at 0x7ffe40915b48
character1 : C, at 0x7ffe40915b3d
character2 : B, at 0x7ffe40915b3e
character3 : D, at 0x7ffe40915b3f
string1 : Hi!, at 0x7ffe40915b4c
string2 : :D, at 0x7ffe40915b50
string3 : ack!, at 0x7ffe40915b54

编辑:编译:GCC 7.3.0

2 个答案:

答案 0 :(得分:4)

内存中变量的排序是编译器的实现细节。无法保证它的外观。

话虽如此,似乎编译器试图以这样的方式布置变量,使得所有变量都正确对齐,它们之间没有任何填充,即它是为了节省空间。

答案 1 :(得分:1)

请记住,您正在处理自动变量。没有关于如何实现自动变量的正式规范,但在任何你可能会发现它们将在堆栈中的系统中。

(假设没有优化)

如果查看main()函数的生成代码(通常是-S选项),您可能会找到类似

的语句。
  MOV  SP, BP
  DECL #SOMENUMBER, SP

其中SOMENUMBER是主函数对局部变量所需的字节数。

然后编译器为每个变量分配SP寄存器的偏移量。它看起来像那样:

  1(SP) ; is character1
  2(SP) ; is character2
  3(SP) ; is character3
  4(SP) ; is integer1
  8(SP) ; is integer2
  12(SP) ; is integer3
  16(SP) ; is string1
  20(SP) ; is string2
  24(SP) ; is string3

堆栈通常向下增长,因此较低的变量地址将具有较小的偏移量。

然后编译器需要初始化堆栈上的每个位置。

编译器的分配器将弄清楚如何进行这种映射。您需要查看GCC代码,找出它为什么采用它的路径。

投掷

 short short1 ;
 long long long1 ;
 char str[] = "12345" ;

可能会给你一些有趣的结果,看看不同的大小如何影响分配器。