当前位置: 首页 > article >正文

C++_unique_ptr_一个类Frame的普通指针fr初始化一个unique_ptr, 这个普通指针还有管理权吗?

一个类Frame的普通指针fr初始化一个unique_ptr, 这个普通指针还有管理权吗?

在 C++ 中,std::unique_ptr 是一种智能指针,它独占管理其所指向对象的所有权。一旦你用一个普通指针初始化或赋值给一个 std::unique_ptr,这个 unique_ptr 会接管对象的所有权,并且不允许其他指针管理这个对象的生命周期。

让我们来看如下代码示例:

Frame* fr = new Frame(); // 普通指针,动态分配内存 
mypFrame = std::unique_ptr<Frame>(fr); // 用普通指针初始化unique_ptr

解释:

  1. Frame* fr = new Frame();

    • 这行代码动态分配了一个 Frame 对象,并用普通指针 fr 指向它。此时 fr 拥有对 Frame 对象的管理权,负责释放该对象的内存。
  2. mypFrame = std::unique_ptr<Frame>(fr);

    • 这行代码将普通指针 fr 赋给了一个 std::unique_ptrmypFrame 现在接管了 fr 所指向的对象的管理权。
    • 一旦 mypFrame 拥有了对象的所有权,普通指针 fr不再拥有管理权,并且你不能再安全地使用 fr 进行内存管理。尤其是,fr 不应被 delete,否则会导致 双重释放 的问题,因为 mypFrame 会在超出作用域时自动释放该对象。

重要注意:

  • 普通指针 fr 不再具有管理权:虽然 fr 仍然可以指向该对象,但它不再负责释放内存。现在 std::unique_ptr 拥有该对象的所有权并将在合适的时候释放它。
  • 如果你尝试对 fr 执行 delete fr;,这会导致 双重释放(Double Free)问题,因为 std::unique_ptr 会自动在其析构时释放 Frame 对象。

进一步说明:

  • std::unique_ptr 通过其构造函数接管对象的所有权。这意味着对象的生命周期完全由 unique_ptr 控制,而普通指针 fr 丧失了管理权。
  • 在使用 unique_ptr 后,最好将 fr 置为 nullptr 或停止使用它,因为它不再安全地管理对象。

安全使用示例:

Frame* fr = new Frame(); // 普通指针 
std::unique_ptr<Frame> mypFrame(fr); // 将管理权转移给unique_ptr 
fr = nullptr; // 明确将普通指针设为nullptr以防止错误使用

在这个示例中,我们显式地将 fr 设置为 nullptr,以避免意外地使用它来管理已被 unique_ptr 接管的内存。

总结:

  • 一旦 std::unique_ptr 接管了普通指针指向的对象,普通指针将 不再拥有管理权
  • 在转移所有权后,避免使用普通指针来操作该对象,尤其是不要手动调用 delete,以防止内存管理问题。

mypFrame = std::unique_ptr<Frame>(fr); 时, 会对 fr所指向的Frame对象进行析构吗?

在执行 mypFrame = std::unique_ptr<Frame>(fr); 时,不会立即对 fr 所指向的 Frame 对象进行析构。实际上,此时只是将 fr 所指向的对象的管理权转移给了 std::unique_ptr。具体过程如下:

过程解释:

Frame* fr = new Frame(); // 动态分配内存,fr指向一个新的Frame对象 
mypFrame = std::unique_ptr<Frame>(fr); // 将fr指向的对象的管理权转移给unique_ptr
  1. Frame* fr = new Frame();

    • 这行代码在堆上动态分配了一个 Frame 对象,并返回一个指向该对象的普通指针 fr。此时 fr 负责管理这个 Frame 对象的内存,只有通过 delete fr; 才能释放这个对象。
  2. mypFrame = std::unique_ptr<Frame>(fr);

    • 这行代码创建了一个 std::unique_ptr<Frame>,将 fr 所指向的对象的管理权交给 mypFrame
    • 这里 std::unique_ptr 接管了 fr 的指针,但 不会析构或释放 Frame 对象,因为此时 unique_ptr 还没有释放对象的时机。只有当 mypFrame 离开作用域或被重新赋值时,才会对其管理的对象进行析构。
    • 注意fr 仍然可以指向那个 Frame 对象,但它不再拥有管理权,也不应被手动 delete,否则会导致 std::unique_ptr 之后进行双重释放。

何时析构:

对象的析构发生在 std::unique_ptr 销毁或重新赋值时,而不是在初始化时。因此,Frame 对象会在以下情况下被析构:

  1. mypFrame 离开其作用域时
    • 如果 mypFrame 是一个局部变量,当它离开作用域时,std::unique_ptr 的析构函数会被调用,自动释放它所管理的 Frame 对象,并调用该对象的析构函数。
  2. mypFrame 被赋值为另一个 std::unique_ptr
    • 如果 mypFrame 之前已经管理了一个对象,在赋值前会先释放当前管理的对象,然后接管新对象。例如:
mypFrame = std::make_unique<Frame>(); // 先析构原对象,然后管理新对象

小结:

  • 不会立即析构:当你执行 mypFrame = std::unique_ptr<Frame>(fr); 时,fr 所指向的 Frame 对象不会被立即析构,而是将对象的管理权转移给 mypFrame
  • 何时析构Frame 对象的析构发生在 std::unique_ptr 被销毁、超出作用域或被赋值新的对象时。
  • 避免手动删除 fr:一旦 unique_ptr 接管对象,fr 不再拥有管理权,手动调用 delete 会导致双重释放问题。

http://www.kler.cn/a/328277.html

相关文章:

  • git合并分支
  • 微众银行申请专利:不过分丢失泛用能力,提高语音大模型对困难样本学习效率
  • 【面试】前端vue项目架构详细描述
  • 关于安卓模拟器或手机设置了BurpSuite代理和安装证书后仍然抓取不到APP数据包的解决办法
  • 面向服务的软件工程——巨详细讲解商务流程建模符号 (BPMN),一篇章带你入门BPMN!!!(week1)
  • C#编写的日志记录组件 - 开源研究系列文章
  • 蓝桥杯--STM32G431RBT6(TIM定时器的输出频率和占空比,含详细原理介绍和使用方法)
  • Git Stash: 管理临时更改的利器
  • 基于C+++Mysql实现(CS界面)图书管理系统
  • 笔墨歌盛世 丹青绘匠心,艺术赋能“百千万工程”
  • 了解独享IP的概念及其独特优势
  • 【STM32单片机_(HAL库)】4-3【定时器TIM】定时器输入捕获实验配置步骤
  • 大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制
  • 音视频通话 SDK
  • WSL (Linux)配置 Rust 开发调试环境
  • Vue创建一个web项目实现布局和路由
  • opencv实战项目二十八:基于Shi-Tomasi算法的箱子角点检测
  • 解决AWS Organizatiion邀请多个Linker账号数量限额问题
  • iwebsec靶场 解析漏洞通关笔记2-Nginx解析漏洞
  • Git的相关使用(工作常用)
  • 【深度学习基础模型】递归神经网络 (Recurrent Neural Networks, RNN) 详细理解并附实现代码。
  • 深蕾半导体Astra™ SL1620详细介绍,嵌入式物联网处理器
  • C++入门(有C语言基础)
  • 相亲交友系统平台的变革
  • JMeter压测HTTPS 在window 11处理SSL证书认证
  • 个人常用AI工具集合