C++内存分区
c++内存分区主要分为四个部分,分别是代码区,全局区,堆区,栈区。分区的意义在于赋予不同区域的数据不同的生命周期,提高程序编写的灵活性。
1.代码区:
- 代码区中存放的内容是CPU运行过程中的机器指令(即二进制形式的程序代码);
- 存入时间是在编译完成之后,执行可执行程序之前;
- 此部分的数据存储有两个特点:共享和只读。为了防止程序的二义性,以及多次存储相同代码带来的内存浪费,设置代码数据是共享的。为了防止编程过程中出现对代码区域的误操作,而造成不确定的问题出现的情况,故禁止对已经存好的代码进行修改,限制代码区的权限为只读。
2.全局区:
- 全局区存放的数据包括全局变量、静态变量(static修饰的变量)、常量(字符串常量,const修饰的全局常量);
- 存入时间是在编译完成之后,执行可执行程序之前;
- 全局区的空间是由操作系统在程序结束之后自动回收释放的。
3.栈区(stack):
- 栈区存放的数据包括局部变量,const修饰的局部常量,函数参数等;
- 栈区数据空间是由编译器分配并回收释放的;
- 存入时间是在执行可执行程序之后;
- 注意:不能返回局部变量的地址,由于局部变量在函数运行结束后,其空间就被编译器自动回收,如果再调用其地址,极有可能返回的是野指针(其中内容是乱码),这是不希望看到的。
4.堆区(heap):
- 堆区存放的数据是由程序员主动申请的,其空间的回收释放也是由程序员来确定的。(如果程序员没有回收空间,则再程序运行结束后由操作系统回收);
- 存入时间是在执行可执行程序之后;
- 在c++中动态申请空间用的是new实现的,回收空间是用delete实现的,具体的语法如下:
//在堆中申请变量:数据类型 * 变量名 = new 数据类型(空间个数);
int * a = new int(10);//在堆中new一个int型的变量,将10赋给它,new的返回是该变量在堆中的地址,因此要利用指针来接收,指针类型要同变量类型一致
//在堆中申请数组:数据类型 * 数组名 = new 数据类型[数组元素的个数];
int * arr = new int[10];//在堆中new一个int型的数组,申请10个元素的空间,new的返回是该数组首元素在堆中的地址,因此要利用指针来接收,指针类型要同变量类型一致
delete a;//回收堆中a的空间
delete [] arr;//回收堆中数组arr的空间
注意一下定义的区别:
- 全局变量是指定义在函数之外的变量,其作用域位于整个程序范围内,其数据保存在全局区;
- 局部变量是指定义在函数内部的变量,其作用域位于函数内部,其数据保存在栈区;
- 静态变量用static修饰,无论定义在函数内还是函数外,都保存在全局区;
- const修饰的变量是看其定义的位置在函数内还是函数外,决定保存数据在栈区还是全局区。
- 常变量包括字符串常量和const修饰的变量等,其值在程序运行期间不能改变