c++中的const常量书上说一般不分配地址,只在用extern声明或者取其地址的时候才分配地址。但是为什么但一个局部变量声明为常量的时候也会分配地址:
下面是c++源码:
int main() { const int a = 10; }
下面是汇编码:
; 5 : int main() { push ebp mov ebp, esp push ecx ; 6 : const int a = 10; mov DWORD PTR _a$[ebp], 10 ; 为a分配存储空间 ; 7 : ; 8 : ; 9 : ; 10 : } xor eax, eax mov esp, ebp pop ebp ret 0
请问,这是什么原因?
1、该变量在函数栈中,不是静态分配的,是属于栈式存储分配,他和堆式分配都称为动态存储分配,属于程序运行时分配的。
2、const常量书上说一般不分配地址,是指const int global_a = 1; 在函数体外,是全局变量。编译器优化而不分配内存而已,以避免访问内存的低效率。
按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.
静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求.
栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。
静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放.
谢谢回复
和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存。
--那么为什么在编译器在编译时就可以分配函数栈的大小?
而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成
--一个类的大小在编译期应该是可以确定的,所以对象实例的大小在编译器也应该是可以确定的吧?
@chaoguo1234: 编译器进行词法分析、语法分析,不同的编译器根据自身的对齐规则,是可以计算出一个函数调用中的栈空间的大小的。栈的分配是动态的。栈的计算是编译器可以控制的。