C/C++/JAVA内存布局
C与C++的内存机制虽然非常相似,但还是有一些不同的地方。下面让我们一起来看看它们到底有什么区别吧。
(一)C内存机制
1. 栈(Stack):
位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。
2. 堆(Heap) :
由程序员用malloc()/calloc()/realloc()分配空间,free()释放所申请的空间。如果程序员忘记free(),则会造成内存泄漏,程序结束时可能会由操作系统回收,也许就一直占用着直至关机。
3. 全局区/静态区(Global Static Area):
全局变量和静态变量存放区,程序一经编译好,该区域便存在。并且在C语言中初始化的全局变量和静态变量和未初始化的放在相邻的两个区域(在C++中,由于编译器会给全局变量和静态变量自动初始化赋值,所以没有区分了)。由于全局变量一直占据内存空间且不易维护,推荐少用。程序结束时释放。
4. C风格字符串常量存储区:
专门存放字符串常量的地方,程序结束时释放。有的书也叫符号表。
5. 程序代码区:
存放程序二进制代码的区域。
(二)C++内存机制
1. 栈(Stack):
位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。
2. 堆(Heap):
这里与C不同的是,该堆是由new申请的内存,由delete负责释放。
3. 自由存储区(Free Storage):
由程序员用malloc()/calloc()/realloc()分配空间,由free()释放。如果程序员忘记free()了,则会造成内存泄漏,程序结束时可能会有操作系统回收,也许就一直占用着直至关机。 与C的堆机制对应。
4. 全局区/静态区(Global Static Area):
全局变量和静态变量存放区,程序一经编译好,该区域便存在。在C++中,由于编译器会给全局变量和静态变量自动初始化赋值,所以没有区分初始化和未初始化变量。由于全局变量一直占据内存空间且不易维护,推荐少用。程序结束时释放。
5. 常量存储区:
这是一块比较特殊的存储区,专门存储不能修改的常量(如果采用非正常手段更改,当然也是可以的)。
特别注意:
为了验证上述,须在编译的时候增加选项-std=c89。为什么?如果没有加-std=c89这个选项,现在的gcc版本一般都是c99标准,c99中增加了很多C++的特性在里面。影响本文验证。
编译器实现问题,有的编译器会把初始化为0的全局或静态变量也作为未初始化的对待。大概是因为未初始化则编译器自动初始化为零的效果一样吧!