内存分区模型
C++在执行时,将内存从大方向上划分为四个区域,在这些不同区域中存放的数据,会被赋予不同的生命周期,以便我们灵活编程。
1.代码区:由操作系统管理,用于存放函数体的二进制代码
2.全局区:用于存放全局变量和静态变量以及常量
3.栈区:由编译器自动分配、释放,存放函数的参数值和局部变量等
4.堆区:由程序员分配释放,或在程序结束后由操作系统回收
未执行程序之前
在程序编译之后且程序执行之前,会生成一个exe的可执行程序,未执行该程序前有两个区域。
- 代码区
代码区用于存放CPU执行的机器指令,它有共享性和只读性,内存中只需要有一份会被频繁执行的代码即可,而只读防止程序被意外改变 - 全局区
全局变量和静态变量存放在全局区,内部还包括常量区,包括字符串常量和其他常量都可以存放与此。该数据最终所占的内存由操作释放。
执行程序之后
- 栈区
栈区的数据由编译器自动分配释放,主要用于存放函数的参数值和局部变量等等。注意:由于栈上的数据在执行完后就会被释放,因此不要尝试返回局部变量的地址。 - 堆区
堆区由程序员进行分配或释放,若程序员不释放,则会由操作系统自行回收。C++主要使用new关键字开辟堆区内存。
new运算符
new运算符可以将原本储存在栈区的局部变量在堆区中开辟空间并储存,之后new将会返回它在堆区开辟的地址,如果需要读取变量的话则需要利用一个指针读取,new的数据是什么类型,它就会返回一个什么类型的指针。代码实现如下:
int * func()
{
int * p = new int(10);
return 0;
}
int main() {
int *p = func();
cout<<*p<<endl;
这样就能读取局部变量指针p的值10。
delete运算符
堆区的数据如果要被程序员手动释放的话,需要使用delete,及时的释放内存是有效使用内存的关键一步,被释放的内存可供程序的其它部分使用。
//接上面的程序
delete p;
return 0;
}
通过这样的方法,即可释放p指向的内存,但是不会删除指针本身,在这时,该指针就会变成“野指针”,直到将它指向一个新的内存块。
利用new开辟数组
int * arr = new int[10]
这段代码表示在空间中开辟了一个10元素的数组,并传给arr一个首地址的值。
释放数组的时候也要对应为delete[] arr;