c++ 内存管理方式
在c++中内存主要分为5个区:栈区、堆区、全局区(静态区)、文字常量区和代码区。
1. 栈区(stack)
局部变量、函数参数等存储在栈区,并且由编译器自动分配和释放,速度快,但是程序员无法控制。栈的内存空间是连续的,但是内存空间有限。操作方式类似于数据结构中的栈,遵循先进后出的规则。只要栈的内存空间大于所申请的内存空间,系统将会为程序分配内存,或者报异常提示栈溢出。
2.堆区(heap)
通过new/malloc得到值存储在堆区,该堆与数据结构中的堆不是同一概念。需要程序员手动申请(new)和释放(delete)(若程序员不释放,程序结束时可能由OS回收),属于动态分配方式,速度较慢。内存空间几乎没有限制,但是内存空间不连续,因此会产生内存碎片,操作系统有一个记录空间内存的链表,当收到内存申请时,会遍历该链表并找到第一个大于申请空间的节点,然后将该节点分配给程序,并且将该节点从链表中删除。
3.全局区(静态区)
全局变量、静态变量(包括函数体内的静态变量)储存在该区,程序结束时由程序自动释放。其中初始化的全局变量和静态变量存放在DATA段(全局初始化区),未初始化的全局变量和静态变量储存在BSS段(全局未初始化区),BSS区(未初始化区)会在程序开始前自动清零,因此未初始化的全局变量和静态变量在程序执行前就已经默认初始化为0 了。
4.文字常量区
常量字符串存储在该区,而且值不允许修改,程序结束时由系统自动释放。
5.代码区
存放程序的二进制代码
以一段简单的代码为例
int a=1; //全局区(静态区)DATA区
static int b=1; //全局区(静态区)DATA区
int c; //全局区(静态区)BSS区,会默认初始化为0
static int d;全局区(静态区)BSS区,会默认初始化为0
void main()
{
int i=10; //栈区
string s="hello"; //栈区,但是字面值“hello”,存放在文字常量区
static int j=20; //全局区(静态区)
int *p=new int[5]; //通过new将会在堆区得到内存
delete[] p;//堆区分配得到内存需要手动释放
}//整个程序代码存放在代码区
通过以上介绍,再来分析一下为什么全局变量会默认初始化为0,而函数体内部的局部变量不会默认初始化为0。这是因为未初始化的全局变量存放在全局区(静态区)中的BSS区,而BSS区会在程序开始之前自动清零,因此存放在该区的变量会被默认初始化为0。而局部变量存放在栈区,栈区内存空间小,若栈区再设置一个清零操作,会使得后续的函数调用等操作更加缓慢,因此栈区内的局部变量不会默认初始化为0。因此局部变量必须初始化。