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

Qt: 详细理解delete与deleteLater (避免访问悬空指针导致程序异常终止)

前言

珍爱生命,远离悬空指针。

正文

delete

  • 立即删除:调用 delete 后,对象会立即被销毁,其内存会立即被释放。
  • 调用顺序:对象的析构函数会被立即调用,销毁该对象及其子对象。
  • 无事件处理:如果在对象销毁过程中还涉及到信号和槽、事件处理等,直接 delete 可能会导致问题,尤其是在对象正在处理事件时。
  • 适用场景:适用于在确定对象已经不再被使用的情况下,并且不涉及异步处理或事件循环中的删除。
MyWidget *widget = new MyWidget();
delete widget;  // 立即删除对象并释放内存

deleteLater

  • 延迟删除deleteLater 并不会立即销毁对象,而是将销毁任务放入 事件队列,等到当前和其他相关的事件处理完成后才会销毁对象。
  • 异步安全:它适用于对象正在执行某些操作(例如正在响应信号、槽或事件)的情况下,防止对象在事件处理过程中被意外删除而导致崩溃。
  • 事件循环依赖deleteLater 依赖于事件循环(event loop),只有在事件循环的下一个迭代时才会删除对象。如果没有事件循环,该对象可能不会被删除。
  • 适用场景:适用于正在处理事件或信号槽连接的对象,或者需要确保对象在当前操作结束后才安全地删除。
MyWidget *widget = new MyWidget();
widget->deleteLater();  // 延迟删除,等到事件处理完成后才会销毁

不同点总结

  1. 删除时机

    • delete 是同步的,立即删除对象。
    • deleteLater 是异步的,等到事件循环完成后再删除对象。
  2. 使用场景

    • delete 适合在确定对象不会再被使用时直接销毁。
    • deleteLater 适合对象正在处理事件或信号时使用,避免在对象处理完毕之前被删除。
  3. 事件安全性

    • delete 可能会在处理事件时导致崩溃,因为对象会立即被删除。
    • deleteLater 避免了这个问题,确保事件处理完成后再销毁对象。

例子

例如,如果你有一个正在运行的 QWidget,它正在处理某个事件,这时使用 delete 会立即删除该对象,导致未定义行为或崩溃。如果用 deleteLater,对象会等到事件处理完成后再删除。

void MyWidget::someSlot() {
    // 如果这里直接 delete this,可能导致崩溃
    // delete this;

    // 使用 deleteLater 可以安全地删除对象
    this->deleteLater();
}

相同点总结

二者在销毁对象后,尤其是指针指向的对象,只是释放了指针指向的内存,指针仍然会保留其先前的地址,其指针本身并不会被置为nullptr,此时指针就处于悬空状态,被称为悬空指针,网上和书上说访问悬空指针会造成未定义行为,我遇到最多的情况就是程序异常终止,让你摸不着头脑。所以说在将指针释放掉后,一定一定一定要指向nullptr,这在你编程的时候会避免很多问题。

小结


http://www.kler.cn/news/294681.html

相关文章:

  • JAVA并发编程JUC包之CAS原理
  • 概率学 笔记一 - 概率 - 随机变量 - 期望 - 方差 - 标准差(也不知道会不会有二)
  • 【AcWing】853. 有边数限制的最短路(bellman-ford贝尔曼福特算法)
  • 【HTML】script标签asyncdefer
  • 第十五届蓝桥杯青少组省赛成绩查询及国赛考试安排
  • 如何实现加密功能
  • 内置消息支持
  • 【电子通识】洁净度等级划分及等级标准
  • macOS 安装 Homebrew
  • 电子发射与气体导电
  • 用ceres实现lio-sam平面点匹配
  • SVD降维
  • 网络安全威胁与防范
  • Java-数据结构-链表-LinkedList(二)|ू・ω・` )
  • 【牛站 / USACO2007】
  • 图欧科技-IMYAI智能助手24年8月更新日志大汇总(含史诗级更新)
  • 如何在SQL Server中恢复多个数据库?
  • C# 获取当前鼠标位置
  • ansible--yaml
  • SOMEIP_ETS_092: SD_Check_Reaction_to_a_Subscribe_with_ttl_0
  • css前段知识点分享
  • pytest运行方式及前置后置封装详解
  • Docker 进阶构建:镜像、网络与仓库管理
  • mariadb容器
  • 8阶段项目:五子棋(附带源码)
  • 服务器数据恢复—infortrend存储中RAID6数据恢复案例
  • 资料分析系统课-刘文超老师
  • ​T​P​三​面​
  • SIGMOD-24概览Part7: Industry Session (Graph Data Management)
  • Wni11 下 WSL 安装 CentOS