c++ primer c++11 动态内存指针指针真麻烦哇 12

23 篇文章 0 订阅
9 篇文章 0 订阅

12

  • 智能指针 下面三个定义在 memory 头文件中

    • shared_ptr 允许多个指针指向一个对象
    • unique_ptr 独占指针所指向的对象
    • weak_ptr 指向share_ptr所管理的对象
  • 默认初始化的智能指针为空指针nullptr

  • make_shared\<T\>(args)返回一个share_ptr 不传递任何参数时进行值初始化

  • 一般使用动态生存期的资源的类有以下几种原因

    • 程序不知道自己需要使用多少对象
    • 程序不知道所需对象的准确类型
    • 程序需要在对各对象间共享数据
share_ptr
  • share_ptr会自动销毁其管理的对向

  • share_ptr还会自动释放相关联的内存
    当动态对向不在被使用时 share_ptr会自动释放动态对象
    如果是new的对象不再需要的话一定要手动delete 但是share_ptr就可以自动销毁释放
    关于这一点必须注意的是 share_ptr 只有在引用计数为 0 时才会销毁
    举个例子 假设智能指针在一个map中 不需要的话一定要erase掉 不然其指向的内存是不会释放的

new和delete直接管理内存
  • new出来的是默认初始化的 比如auto p = new int;这里的p就默认初始化 所以其值未定义

  • new失败会抛出一个bad_alloc异常

  • delete p;执行两个动作 销毁指针指向的对象 释放内存

  • 传递给delete的必须是new分配的内存或者是空指针nullptr 将相同的指针多次delete也是未定义行为

  • delete之后记得重置为nullptr可以稍微避免多次delete 但是这只能提供有限的保护 并不能确定没有其他指针还指向这块被释放的内存
    如下这个p被delete之后释放了其指向的内存 其实q此时也无效了 但是却无法检测 这就是直接new和delete最大的弊端

    	int *p(new int(42));
    	auto q = p;
    	delete p;
    	p = nullptr;
    
share_ptr和new结合使用
  • 可以使用new返回的指针去初始化智能指针 接受指针参数的构造函数是explicit的只能使用直接初始化

  • 当一个share_ptr绑定到一个new的普通指针时 那个就不应该在使用这个内置指针 因为你不知道什么时候对象会被智能指针销毁

  • 智能指针定义了一个get方法 返回一个内置指针

    • 使用get返回指针的代码不能delete此指针 delete了那就gg
    • 将另一个智能指针绑定到这个get返回的指针也是错误的 因为这样会使两个独立的智能指针指向一个内存
      这样一个智能指针失效释放了 会导致另一个智能指针的行为未定义 gg
  • 智能指针陷阱

    • 不要用相同的内置指针值初始化或者reset多个智能指针
    • 同上不能用 get() 返回的指针初始化或者reset另一个智能指针
    • 不能delete get() 返回的指针
    • 使用了 get() 返回指针的话 需要记住在share_ptr释放之后这个 get() 的指针会无效
    • 智能指针管理的不是new的资源记住需要传递一个delete参数
unique_ptr 和 weak_ptr
  • 特别要记住release成员函数不会释放内存

  • unique_ptr独占对象 所以不允许拷贝 但是有一个例外情况 可以拷贝或者赋值一个将要被销毁的对象 参考后面的
    最常见的例子就是可以从函数返回一个unique_ptr对象

  • weak_ptr是一个不管理对象生存周期的指针 指向一个shared_ptr管理的对象
    将weak_ptr绑定到shared_ptr不会增加shared_ptr的引用计数

  • weak_ptr的对象可能不存在 简单使用如下

    if (shared_ptr<int> np = wp.lock()){}
    
  • 这里有一个使用智能指针定义begin和end的例子

动态数组
  • new int[0] 个数为0也是允许的 但是这返回的指针类似尾指针的效果 无法解引用 可以像使用尾指针一样始终这个返回的指针

  • delete [] pa; 会逆序销毁元素

  • 指向数组的unique_ptr unique_ptr<int[]> u;
    u.release()会执行delete []释放数组 这与普通unique_ptr不一样 普通的unique_ptr的release不会释放内存

  • 指向数组的unique_ptr支持下标运算

  • shared_ptr不直接数组 管理动态数组的话需要自定义删除器 并且不支持下标运算符 绑定数组的话需要使用get()+n进行访问
    使用lambda传递delete参数shared_ptr<int> sp(new int[10], [](int *p){delete []p;})

allocator类
  • new将分配内存和对象的构造结合在了一起 delete将对象的析构和内存的释放组合在了一起
    没有默认构造函数的类也无法动态分配数组

  • allocator定义在memory中 帮助我们将内存分配和对象构造分开 使用未构造的内存其行为未定义

  • 具体方法P428

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值