ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

智能指针与动态内存

2026/8/17 15:07:21 拓冰建站 浏览量
智能指针与动态内存

动态内存

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 的所有权。

    1. unique函数:判断该shared_ptr对象是否独占若独占,返回true。否则返回false。

    1. reset函数:
      • 当reset函数有参数时,改变此shared_ptr对象指向的内存。
      • 当reset函数无参数时,将此shared_ptr对象置空,也就是将对象内存的指针设置为nullptr。

new和share_ptr

智能指针构造函数是explicit的

指定内存回收逻辑

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

常用函数

    1. unque_ptr禁止复制构造函数,也禁止赋值运算符的重载。否则独占便毫无意义。、
    1. unqiue_ptr允许移动构造,移动赋值。移动语义代表之前的对象已经失去了意义,移动操作自然不影响独占的特性。
    1. 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;};