• 动态内存与智能指针


    一、三大内存区域

    栈内存:保存定义在函数内的非static对象。
    静态内存:保存局部static对象,类static数据成员以及定义在任何函数之外的变量。
    堆(自由空间):存储动态分配的对象。
    程序使用动态内存出于以下三种原因之一:
    1、程序不知道自己需要使用多少对象
    2、程序不知道所需对象的准确类型
    3、程序需要在多个对象间共享数据

    二、动态内存与智能指针

    头文件:memory

    1、运算符new、delete

        new:在动态内存中为对象分配空间并返回一个指向对象的指针。
        delete:接收一个动态对象的指针,销毁对象,并是释放与之关联的内存。

    2、shared_ptr类

    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6.         shared_ptr p;
    7.         //如果p不为空,检查它是否指向一个空string
    8.         if (p && p->empty())
    9.         {
    10.         }
    11.         return 0;
    12. }

        每个shared_ptr都有一个关联的计数器,称为引用计数。该计算器记录了一个对象被多少个智能指针指向。shared_ptr的析构函数会递减它所指向的对象的引用计数。如果引用计数变为0,shared_ptr的析构函数就会销毁对象,并释放
    执行delete运算符后,先调用对象的析构函数,后释放内存
    指定d(替代delete)后,在对象应该释放时将调用d(即使原来有析构函数,也是调用d而不调用原始函数),在d中需要使用delete运算符释放内存。
    1. #include
    2. #include
    3. #include"test.h"
    4. #include"testClass.h"
    5. using namespace std;
    6. void f(testClass* p)
    7. {
    8.     cout << "f" << endl;
    9.     delete p;
    10. }
    11. int main()
    12. {
    13.     testClass* p;
    14.     if (true)
    15.     {
    16.         shared_ptr sp(new testClass("123"),f);
    17.         p = sp.get();
    18.     }
    19.     p->name = "456";//以及释放,不能正确执行
    20.     return 0;
    21. }
    (1)当对象的引用计数为0,但有其他指针指向它时,该对象是否会被销毁?
    答:会销毁
    (2)make_shared函数
        最安全的动态内存分配方法是调用make_shared的标准库函数。此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr。
    1. shared_ptr p1 = make_shared();
    2. auto p2 = make_shared("CDA");

    3、unique_ptr类

        某个时刻只能有一个unique_ptr指向一个给定对象,当unique_ptr被销毁时,它所指向的对象也被销毁。
        
        因为某时刻只能一个unique_ptr指向一个给定对象,所以不能拷贝unique_ptr,但是有一个例外,我们可以拷贝或赋值一个将要被销毁的unique_ptr。例如:
    注:
    向unique_ptr传递删除器
    unique_ptr<对象类型,删除器类型> p(new 对对象类型,删除器);
      
    (1)能否让一个unique_ptr和一个shared_ptr指向同一个对象
    运行时发生错误。
    结论:unique_ptr指向一个对象后,便不能再有智能指针指向该对象。

    4、weak_ptr

        weak_ptr是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就被释放。即使有weak_ptr指向对象,对象也还是会被释放。
    由于对象可能不存在,我们不能使用weak_ptr直接访问对象,而必须调用lock。
    1. weak_ptr wp(make_shared("123"));
    2. if (auto sp = wp.lock())//判断是否为空
    3. {
    4. }

    5、使用规范

    delete内存后将指针赋值为nullptr,表示指针不再绑定到任何对象
  • 相关阅读:
    docker pull 拉取镜像报错
    【光学】基于Matlab模拟干涉条纹图
    周赛补题
    Letbook Cookbook题单——数组2
    autoware open_planner
    centos下安装mysql8版本
    负载均衡的原理和算法
    C语言入门(二)运算符和表达式
    linux之权限管理命令
    js 对象循环遍历
  • 原文地址:https://blog.csdn.net/weixin_50836068/article/details/125978546