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

本文主要是介绍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,这在你编程的时候会避免很多问题。

小结

这篇关于Qt: 详细理解delete与deleteLater (避免访问悬空指针导致程序异常终止)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1147424

相关文章

Python实现一键PDF转Word(附完整代码及详细步骤)

《Python实现一键PDF转Word(附完整代码及详细步骤)》pdf2docx是一个基于Python的第三方库,专门用于将PDF文件转换为可编辑的Word文档,下面我们就来看看如何通过pdf2doc... 目录引言:为什么需要PDF转Word一、pdf2docx介绍1. pdf2docx 是什么2. by

Python程序的文件头部声明小结

《Python程序的文件头部声明小结》在Python文件的顶部声明编码通常是必须的,尤其是在处理非ASCII字符时,下面就来介绍一下两种头部文件声明,具有一定的参考价值,感兴趣的可以了解一下... 目录一、# coding=utf-8二、#!/usr/bin/env python三、运行Python程序四、

Logback在SpringBoot中的详细配置教程

《Logback在SpringBoot中的详细配置教程》SpringBoot默认会加载classpath下的logback-spring.xml(推荐)或logback.xml作为Logback的配置... 目录1. Logback 配置文件2. 基础配置示例3. 关键配置项说明Appender(日志输出器

redis在spring boot中异常退出的问题解决方案

《redis在springboot中异常退出的问题解决方案》:本文主要介绍redis在springboot中异常退出的问题解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴... 目录问题:解决 问题根源️ 解决方案1. 异步处理 + 提前ACK(关键步骤)2. 调整Redis消费者组

无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案

《无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案》:本文主要介绍了无法启动此程序,详细内容请阅读本文,希望能对你有所帮助... 在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是"api-ms-win-core-path-l1-1-0.dll丢失

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red

Java内存区域与内存溢出异常的详细探讨

《Java内存区域与内存溢出异常的详细探讨》:本文主要介绍Java内存区域与内存溢出异常的相关资料,分析异常原因并提供解决策略,如参数调整、代码优化等,帮助开发者排查内存问题,需要的朋友可以参考下... 目录一、引言二、Java 运行时数据区域(一)程序计数器(二)Java 虚拟机栈(三)本地方法栈(四)J

NGINX 配置内网访问的实现步骤

《NGINX配置内网访问的实现步骤》本文主要介绍了NGINX配置内网访问的实现步骤,Nginx的geo模块限制域名访问权限,仅允许内网/办公室IP访问,具有一定的参考价值,感兴趣的可以了解一下... 目录需求1. geo 模块配置2. 访问控制判断3. 错误页面配置4. 一个完整的配置参考文档需求我们有一

Qt之QMessageBox的具体使用

《Qt之QMessageBox的具体使用》本文介绍Qt中QMessageBox类的使用,用于弹出提示、警告、错误等模态对话框,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.简单介绍3.常见函数4.按钮类型(QMessage::StandardButton)5.分步骤实现弹窗6.总结1.引言

Qt中Qfile类的使用

《Qt中Qfile类的使用》很多应用程序都具备操作文件的能力,包括对文件进行写入和读取,创建和删除文件,本文主要介绍了Qt中Qfile类的使用,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.QFile文件操作3.演示示例3.1实验一3.2实验二【演示 QFile 读写二进制文件的过程】4.