动态内存
new
placement new
是 C++ 中的一种内存分配方式,它允许在给定的内存地址上构造对象,而不是在默认的堆上分配新的内存。这对于某些特殊的内存管理场景非常有用,例如在特定的内存池中分配对象。
C++11 引入了 "new auto" 语法,它允许你使用 auto
关键字来推断要分配的对象的类型。使用 "new auto" 的语法可以简化代码,特别是在创建复杂的类型或者使用模板时。
// 使用 new auto 分配整数auto* myInt = new auto(42);// 使用 new auto 分配浮点数auto* myDouble = new auto(3.14);
alignas
是 C++11 引入的一个关键字,用于指定对齐方式。它可以用于变量、类型、结构体、类等,使得相应的对象或结构体成员按照指定的对齐方式进行对齐。
new会考虑struct的对齐信息
delete
不要delete非new返回的内存
智能指针
所有权不清晰 没销毁
解决方法:
share_ptr
常用接口
1. get
函数:
get
函数用于获取指向所管理对象的原始指针。这个原始指针可以用于调用不接受智能指针的函数或与 C 接口进行交互。需要注意的是,get
函数返回的是一个裸指针,它不负责引用计数,也不会影响 std::shared_ptr
的所有权。
-
- unique函数:判断该shared_ptr对象是否独占若独占,返回true。否则返回false。
-
- reset函数:
- 当reset函数有参数时,改变此shared_ptr对象指向的内存。
- 当reset函数无参数时,将此shared_ptr对象置空,也就是将对象内存的指针设置为nullptr。
- reset函数:
指定内存回收逻辑
C++17和20支持的数组
new数组和delete不匹配现象
C++17和20解决方法
#include<iostream>
#include<memory>int main(){std::shared_ptr<int>x(new int[5]);//delete(x.get())//C++17做法std::shared_ptr<int[]>x2(new int[5]);//C++20做法auto x3=std::shared_ptr<int[5]>();return 0;
}
unique_ptr
常用函数
-
- unque_ptr禁止复制构造函数,也禁止赋值运算符的重载。否则独占便毫无意义。、
-
- unqiue_ptr允许移动构造,移动赋值。移动语义代表之前的对象已经失去了意义,移动操作自然不影响独占的特性。
-
- reset函数:
- 不带参数的情况下:释放智能指针的对象,并将智能指针置空。
- 带参数的情况下:释放智能指针的对象,并将智能指针指向新的对象。
- reset函数:
unique_ptr要传入del
weak_ptr和循环引用
x,y形成环 循环引用
智能指针实现原理
析构两次的解决方法
auto_ptr:管理权转移
template<class T>class auto_ptr {public:auto_ptr(T* ptr) :_ptr(ptr) {}auto_ptr(auto_ptr<T>& ap) :_ptr(ap._ptr) {ap._ptr = nullptr;}~auto_ptr(){if (_ptr) {cout << "delete:" << _ptr << endl;delete _ptr;_ptr = nullptr;}}T& operator*() {return *_ptr;}T* operator->() {return _ptr;}private:T* _ptr;};
缺陷:auto_ptr的问题:当对象拷贝或者赋值后,前面的对象就悬空了
C++98中设计的auto_ptr问题是非常明显的,所以实际中很多公司明确规定了不能使用auto_ptr
unique_ptr:防拷贝
template<class T>class unique_ptr {public:unique_ptr(T* ptr) :_ptr(ptr) {}unique_ptr(unique_ptr<T>& ap) :_ptr(ap._ptr) {ap._ptr = nullptr;}unique_ptr<T>& operator=(unique_ptr<T>& up) = delete;~unique_ptr(){if (_ptr) {cout << "delete:" << _ptr << endl;delete _ptr;_ptr = nullptr;}}T& operator*() {return *_ptr;}T* operator->() {return _ptr;}private:T* _ptr;};
shared_ptr:引用计数
shared_ptr的原理:是通过引用计数的方式来实现多个shared_ptr对象之间共享资源。
1. shared_ptr在其内部,给每个资源都维护了着一份计数,用来记录该份资源被几个对象共享。
2. 在对象被销毁时(也就是析构函数调用),就说明自己不使用该资源了,对象的引用计数减一。
3. 如果引用计数是0,就说明自己是最后一个使用该资源的对象,必须释放该资源;
4. 如果不是0,就说明除了自己还有其他对象在使用该份资源,不能释放该资源,否则其他对象就成野指针了。
template<class T>class shared_ptr {public:shared_ptr(T* ptr) :_ptr(ptr),_pcount(new int(1)) {}shared_ptr(shared_ptr<T>& sp) :_ptr(sp._ptr),_pcount(sp._pcount){++(*_pcount);}shared_ptr<T>& operator=(shared_ptr<T>& sp) {if (this != &sp) {if (--(*_pcount) == 0) {delete _pcount;delete _ptr;}_ptr = sp._ptr;_pcount = sp._pcount;++(*_pcount);}return *this;}~shared_ptr(){if (--(*_pcount)==0&&_ptr) {cout << "delete:" << _ptr << endl;delete _ptr;_ptr = nullptr;}}T& operator*() {return *_ptr;}T* operator->() {return _ptr;}private:T* _ptr;int *_pcount;};