【问题标题】:Does the C compiler allocate memory for a variable? [duplicate]C 编译器是否为变量分配内存? [复制]
【发布时间】:2017-12-24 16:31:50
【问题描述】:

我想知道在哪个阶段,内存被分配给变量。 是在编译阶段还是在执行阶段?

【问题讨论】:

    标签: c


    【解决方案1】:

    是的,是的,两者都是。

    对于全局变量(在文件范围内声明),编译器保留可执行映像中的内存。所以这是编译时。

    对于自动变量(在函数中声明),编译器添加指令在堆栈上分配变量。所以这是运行时

    int a;        // file scope
    
    int f(void)
    {
        int b;    // function scope
        ...
    

    注意事项:

    • 编译器有一个(一组)指令来一次性分配函数的所有局部变量。一般来说,每个变量都没有开销(可能会有我现在不讨论的例外情况)。每次调用函数时都会执行这些指令。

    • 编译器不会为你的字符串分配存储空间。这是初学者经常犯的错误。考虑:

      char *s;         // a pointer to a strings
      scanf("%s", s);  // no, the compiler will not allocate storage for the string to read.
      

    【讨论】:

    • 好的,所以当声明变量时,编译器如何存储它,它是否存储在任何符号表中。如果是这样,这个符号表包含什么?当变量被定义时,我们说变量被分配了一些内存并分配了一些值。
    • 编译器计算变量的位置(全局变量的绝对位置,例如mov ax, [0x06B7D3],或局部变量的相对位置,例如mov ax,[bp+8])并将这些计算值放入机器指令中。不需要运行时符号表。
    • 我的问题是,当一个变量被声明时,比如 extern int a;编译器做什么,以及何时将相同的变量定义为 int a;编译器是做什么的?
    • 是的,编译器在编译程序时使用符号表。 extern int a 将在当前编译单元的符号表中生成一个 a 将存在的条目。但是,只有在链接期间必须解析 a,即在目标文件或库之一中找到作为存储位置。
    • 所以extern int a 表示“a 存在于其他地方”,int a 在文件范围内表示“a 在此处定义;请保留存储空间。”
    【解决方案2】:

    这取决于变量/对象的种类。

    全局和静态分配的变量在编译时是已知的,它们在data segment 中的偏移量烘焙到程序中。所以在某种程度上,它们在编译时得到了分配

    函数作用域的局部变量在stack. 上分配您可以说编译器知道它们以及它们所需的存储类型,但显然它们已分配 (在存在的意义上)在运行时,在函数调用期间。

    另一个有趣的对象是堆分配对象,它可以用 C 中的 malloc/calloc 和 C++ 中的新机制或相关机制来创建。它们在运行时分配在堆部分中。

    【讨论】:

      【解决方案3】:

      还有第三种内存,使用malloc()和朋友动态分配。

      此内存取自所谓的堆。而自动变量(你在函数中)是从所谓的堆栈中获取的。

      然后,如果您的变量带有一个从不改变值的初始化程序(例如int i = 5;),编译器可能会发现这一点并且根本不分配内存。相反,它只会在您在代码中使用该变量的任何地方使用5

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-20
        • 1970-01-01
        • 2016-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-29
        相关资源
        最近更新 更多