我在 C 中声明了一个变量。编译器如何为变量分配内存 space?

I declared a variable in C. How come compiler allotted a memory space for variable?

作为一个初学者,我了解到在 C 中只有变量定义分配了内存。但是对于以下程序,输出是 0x7ffd12792034

#include<stdio.h>


int main(char args[], int vargs)
{
  int max;
  printf("%p\n", &max);
}

A local variable is likely to sit on the call stack (but sometimes the compiler would optimize to put it only in some processor register 甚至完全忘记它)。您的 int max; 是局部变量定义。它的初始值是不确定的,这实际上意味着它保留了之前内存位置(或寄存器)中的任何内容。

您的程序正在打印调用堆栈上的局部变量的地址。

由于 ASLR 从一个程序执行到下一个程序执行,该地址的实际值可能会改变(或不变)。它是特定于实现的。

顺便说一句,你应该在编译时启用所有警告和调试信息。如果你使用 GCC, you should compile with gcc -Wall -Wextra -g. You would then have some warnings at least, in particular because your main function has the wrong signature. It should be int main(int argc, char**argv) and the runtime environment guarantee that argc is at least 1 and that the argv array is NULL terminated, with argc arguments which are non-NULL unaliased 个字符串。

提防undefined behavior.

在这种情况下,您实际上定义了一个变量,而不是声明一个。

如果您使用了 extern 关键字,您将有一个声明。但是因为你没有,所以你有一个定义。

int max = 1; 等初始值设定项不需要定义。该值将是未指定的,直到它被分配一个之后,但它仍然是一个定义。

如果您在没有初始值设定项的情况下在文件范围内声明变量,您将得到一个暂定定义。然后您可以稍后使用初始化器进行完整定义,但它必须与暂定定义的类型相匹配。

您正在打印内存中已占用 int max 并准备初始化的地址。通过键入 int max,如果您给它赋值,您已经有了存储变量的位置。

C 抽象机没有像您的情况那样定义编译器将在何处分配原子数据类型。

查看特定实现的唯一方法是反汇编它。

  4004d7:       55                      push   %rbp
  4004d8:       48 89 e5                mov    %rsp,%rbp
  4004db:       48 83 ec 10             sub    [=10=]x10,%rsp
  4004df:       48 8d 45 fc             lea    -0x4(%rbp),%rax
  4004e3:       48 89 c6                mov    %rax,%rsi
  4004e6:       bf 84 05 40 00          mov    [=10=]x400584,%edi
  4004eb:       b8 00 00 00 00          mov    [=10=]x0,%eax
  4004f0:       e8 fb fe ff ff          callq  4003f0 <printf@plt>
  4004f5:       b8 00 00 00 00          mov    [=10=]x0,%eax
  4004fa:       c9                      leaveq 
  4004fb:       c3                      retq   
  4004fc:       0f 1f 40 00             nopl   0x0(%rax)

在这种情况下,它在堆栈上的偏移量 -4-base_pointer 处为其分配了 space -- -0x4(%rbp).