内存分区模型
C++程序在执行时,将内存大致分为4个取区域。
代码区:存放函数体的二进制代码,由操作系统进行管理。
全局区:存放全局变量和静态变量以及常量
栈区:由编译器自动分配释放,存放函数的参数值、局部变量等
堆区:由程序员分配和释放,若程序员不释放,则程序结束时由操作系统回收
代码区
在程序编译后,生成了.exe可执行程序,未执行该程序前分配代码区。
代码区存放CPU执行的机器指令(二进制)
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。
代码区是只读的,防止程序被意外地修改。
全局区
未执行该程序前就被分配。
全局变量(函数外)和静态变量(static)存放在此。
全局区还包含了常量区(字符串常量、const修饰的常量)
该区域的数据在程序结束后有操作系统释放。
栈区
由编译器自动分配释放,存放函数的参数值、局部变量等。
注意:不要返回局部变量的地址,栈区开辟的数据在函数执行完后由编译器自动释放。
堆区
由程序员分配释放,若程序员不释放,则程序结束时由操作系统回收。
在C++中主要利用new来在堆区开辟内存,new返回创建对象的内存地址,需要用指针来接收。
#include <iostream>
using namespace std;
int * func(){
//利用new关键字,可以将数据开辟到堆区
// new int(10) 会返回一个int型地址,即返回开辟内存的地址
int * p = new int(10); //p指针为局部变量,放在栈区;指针保存的数据放在堆区
return p; //返回的是局部变量,而不是局部变量的地址,此局部变量是地址
}
int main(){
int * p = func();
cout << *p <<endl; //解引用
return 0;
}
new操作符
#include <iostream>
using namespace std;
//new的基本语法
int * func(){
//在堆区创建整型数据
//new返回该数据类型的指针
int * p = new int(10);
return p;
}
void test01(){
int * p = func();
cout << *p <<endl;
cout << *p <<endl;
cout << *p <<endl;
//堆区数据有程序员开辟释放
//利用关键字 delete 来释放堆区数据
delete p; //delete后直接加 new的返回
}
//在堆区利用new开辟数组
void test02(){
//创建一个size为10数组
int * arr = new int[10]; //[]表示创建数组,返回首地址
for(int i=0; i<10; i++){
arr[i] = i;
}
for(int i=0; i<10; i++){
cout <<arr[i]<<" ";
}
cout <<endl;
//释放数组
delete[] arr; //[] 表示释放的是数组
}
int main(){
//new的基本语法
test01();
在堆区利用new开辟数组
test02();
return 0;
}