【发布时间】:2017-12-24 16:31:50
【问题描述】:
我想知道在哪个阶段,内存被分配给变量。 是在编译阶段还是在执行阶段?
【问题讨论】:
标签: c
我想知道在哪个阶段,内存被分配给变量。 是在编译阶段还是在执行阶段?
【问题讨论】:
标签: c
是的,是的,两者都是。
对于全局变量(在文件范围内声明),编译器保留可执行映像中的内存。所以这是编译时。
对于自动变量(在函数中声明),编译器添加指令在堆栈上分配变量。所以这是运行时
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 将在当前编译单元的符号表中生成一个 a 将存在的条目。但是,只有在链接期间必须解析 a,即在目标文件或库之一中找到作为存储位置。
extern int a 表示“a 存在于其他地方”,int a 在文件范围内表示“a 在此处定义;请保留存储空间。”
这取决于变量/对象的种类。
全局和静态分配的变量在编译时是已知的,它们在data segment 中的偏移量烘焙到程序中。所以在某种程度上,它们在编译时得到了分配。
函数作用域的局部变量在stack. 上分配您可以说编译器知道它们以及它们所需的存储类型,但显然它们已分配 (在存在的意义上)在运行时,在函数调用期间。
另一个有趣的对象是堆分配对象,它可以用 C 中的 malloc/calloc 和 C++ 中的新机制或相关机制来创建。它们在运行时分配在堆部分中。
【讨论】:
还有第三种内存,使用malloc()和朋友动态分配。
此内存取自所谓的堆。而自动变量(你在函数中)是从所谓的堆栈中获取的。
然后,如果您的变量带有一个从不改变值的初始化程序(例如int i = 5;),编译器可能会发现这一点并且根本不分配内存。相反,它只会在您在代码中使用该变量的任何地方使用5。
【讨论】: