一. 在编译运行程序的过程中,内存的分配使用状况:
1.静态内存:局部static对象 类static数据成员 定义在函数之外的变量
2.栈内存:保存定义在数据内的非static对象
分配在静态或者栈内存中的对象由编译器自动创建和销毁,栈对象仅在程序块运行时才存在,static对象在使用之前分配,在程序结束时销毁
3.堆(内存池,自由空间):存储动态分配的对象,即是程序运行时分配的对象,其生命期由程序来控制,动态对象不再使用时,代码必须显示的销毁
二. 动态内存与new/delete运算符
c++动态内存管理,通过new/delete运算符来完成的。
new:为对象分配空间并返回一个指向该对象的指针;
delete: 接受一个动态对象的指针,销毁该对象,并释放与之关联的内存
动态内存的弊端:
1.申请的内存忘记释放,造成内存泄漏
2.当前指针提前释放有其他指针引用的内存,造成产生引用非法内存的指针
直接内存管理
new动态分配和初始化对象
普通内置类型指针的初始化方式: 默认初始化 类类型的对象初始化使用默认构造函数进行初始化 string *ps = new string; // 初始化为空的string 内置类型或者组合类型的对象将是未定义的; int *pi = new int; // pi指向一个未初始化的int 直接初始化方式 int *pi = new int(1024); // 直接初始化 string *ps = new string(10, 'a'); // *ps 为"aaaaaaaaaa" 赋值初始化方式
delete:销毁给定的指针指向的对象以及释放对应的内存
传递给delete的指针必须指向动态分配的内存,或者一个空指针
动态对象的生命期直到被释放时为止
Tips:delete一个指针后,指针会变无效,但是机器上指针仍然保留着(已经释放的)动态内存的地址,在delete后,指针就变成了“空悬指针”,为了避免,释放掉的指针成为指向一块曾经保存数据但现在已经无效的内存的指针,在delete之后将nullptr赋予指针,使指针不指向任何对象。
int i, *pi = &1, *pi2 = nullptr; double *pd = new double(3), *pd2 = pd; delete i; //错误: i是一个整型常量,不是指针 delete pi; //错误:指针pi指向局部变量,不再动态内存区 delete pd; // 正确 delete pd2; // 未定义,pd2指向内存已经被pd释放了 delete pi2; //正确,delete空指针