内存管理
- 内存管理方式
-
- 交互给用户管理 ----- C语言
- GC机制,垃圾回收机制 ----- Java
- C++为什么没有GC机制??? ------ C++内存管理方式:计数管理+智能指针
- 答:
- 智能指针:帮助用户自动管理内存 ------ 包含头文件#include <memory>
- shared_ptr ---- 共智能指针
- 概念:允许多个共享智能指针指向同一个对象,并对指向该对象的指针计数,当计数到0时会释放该对象
- shared_ptr是一个类,而且是explicit,所以禁止隐式的类型转换(不可以在定义对象的时候使用“=”)
- 大小:裸指针的两倍
- 计数的增加和减少
- shared_ptr ---- 共智能指针
-
-
- 定义一个共享指针:
- shared_ptr的一些常规操作:
- use_count():查看有多少和shared_ptr指针指向同一个对象
- unique():查看该智能指针是否独占某一个对象,是---> 1
- reset():无参时表示将该指针置为nullptr或者释放;有参时将该指针指向新的对象或者释放
- get():获取该指针的裸指针(兼容C语言)
- 定义一个共享指针:
-
-
-
-
- 指定删除器: shared_ptr指针的指向相同,则其类型就相同!!!
-
-
pt的类型为Test[ ] 所以删除的时候需要指定相同的类型
pt2类型为Test[ ],由于没有指定删除器,则pt2就被当成Test*删除,导致析构出错
-
-
-
- std::move()
-
-
// shared_ptr<Test> &&pt3 = std::move(pt2);
-
- week_ptr ---- 弱指针
- 定义一个week_ptr:
- week_ptr ---- 弱指针
-
-
- 不会改变对象的计数引用的个数!
- 大小:裸指针的两倍
- 用来辅助shared_ptr来监视对象的生存周期。
- 常规操作:
- use_count():查看多少个shared_ptr指向该对象
- lock():用于转换成shared_ptr指针;
- reset():
- expired():查看弱指针是否过期
- unique_ptr ---- 独占指针
- 不支持拷贝和赋值的操作
- 大小和裸指针的大小相同
- 常规操作:
- release():放弃对该对象的控制权,并将其释放;
- reset();
- get():获取裸指针
- 指定删除器: 指向不同的对象时就是不同类型的指针
-
- new operator 分配新的空间,调用operator new
- operator new 运算符
- 右值引用本身是一个左值,可以对其进行修改操作。!!!
2、内存管理
- 重载new、delete、new[ ]、delete[ ]
-
- 何时使用:实现内存管理,提高内存使用效率的时候
- 重载new[ ]的时候会多出一个指针来管理分配的空间,其中就保存了需要delete的字节数
- new、delete和构造函数、析构函数的调用顺序:
- 先调用new,再调用构造函数
- 先调用析构函数,在调用delete
Test *p1 = new Test(1);
delete p1;
结果:
my operator new :4 // new
Test() // 构造函数
~Test() // 析构函数 析构类对象中的成员!!!
my operator delete // delete 删除指针
补充:析构函数的调用时机:
1、当创建一个类的对象的时候,当该类对象离开其作用域或者程序退出的时候,系统会自动调用析构函数。
2、当创建了一个类指针,如果用户没有delete该指针,则系统不会自动调用析构函数,只有当用户delete时会调用析构函数,顺序如上。
- placement new:定位new,在指定的空间(已有的内存空间)上分配内存;
static void * operator new(size_t size, void *p) //placement new
{
printf("p = %p\n",p);
return p;
}
int num = 5;
int * p = #
int * p1 = new(p1) int;
-
- 作用:硬件编程,把一个地址映射成为一个对象地址,从而达到对对象的操作转化成对地址的操作。
- Linux 进程间的通信 : 共享内存
- C++分配内存的两种机制:new/delete
- callor、malloc、realloc
-
- calloc:void * calloc(int nmemb, size_t size); 分配一个内存块
- realloc:void * realloc(void *ptr, size_t size); 在一块内存上面继续追加
- 内存池
- 实现思路:1、链表 2、嵌入式指针
具体实现: