1.内存分区模型
- 代码区:存放函数体的二进制代码,由操作系统进行管理
- 全局区:存放全局变量和静态变量以及常量
- 栈区:由编译器自动分配和释放,存放函数的参数值,局部变量等
- 堆区:由程序员分配和释放,若没有释放,程序结束时由操作系统回收
2.1程序运行前
- 代码区:
存放cpu执行的机器指令
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码
代码区是只读的,只读的原因是防止程序意外的修改了它的指令
- 全局区
全局变量和静态变量存放在这
全局区还包括了常量区,字符串常量和其他常量也存放在这
该区域在程序结束后由操作系统进行释放
#include <iostream>
using namespace std;
/*全局变量*/
int a = 10;
const int c_a = 20;
int main()
{
/* 存放在全局区的数据有:
* 全局变量
* 静态变量
* 常量:字符串常量和全局常量
*/
/*静态变量,即在变量前面加上static*/
static int s_a = 20;
/*常量,包扩字符串常量和全局常量,但是不包括局部常量*/
cout << "全局变量的地址" << (&a) << endl;
cout << "静态变量的地址" << (&s_a) << endl;
cout << "字符串常量的地址" << (&"hello world") << endl;
cout << "全局常量的地址" << (&c_a) << endl;
return 0;
}
2.2.程序运行后
- 栈区
由编译器自动分配释放,存放函数的参数值和局部变量等。
#include <iostream>
using namespace std;
/* 栈区的注意事项——不要返回局部变量的地址
* 栈区的数据由编译器管理开辟和释放
*/
int* fun(int b) //形参也存放在栈区
{
b = 10;
int a = 20; //局部变量存放在栈区,函数执行完会自动释放
return &a;
}
int main()
{
int* p = fun();
cout << *p << endl; //第一次可以打印,因为编译器做了保留
cout << *p << endl; //第二次不可以打印,因为局部变量已经被释放
return 0;
}
- 堆区
由程序员分配释放,如果不释放,系统回收
#include <iostream>
using namespace std;
/* 堆区的数据只要不释放,就一直存在
*/
int* fun()
{
int* p = new int(10); //指针本质上也是局部变量,放在栈上,指针保存的数据是放在堆上的
return p;
}
int main()
{
int* p = fun();
cout << *p << endl; //第一次可以打印,因为编译器做了保留
cout << *p << endl; //第二次还是可以打印
return 0;
}
3.关于什么时候用new,什么时候不要new
- 申请动态内存,数量不确定
- 需要的空间比较大
- 对于对象的范围有要求
当使用new的时候,背后完成的操作
- 获得一块内存空间
- 调用构造函数
- 返回正确的指针
使用delete时
- 调用析构函数
- 释放内存