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

C++(Qt)软件调试---内存分析工具Heob(26)

C++(Qt)软件调试—内存分析工具Heob(26)


文章目录

  • C++(Qt)软件调试---内存分析工具Heob(26)
    • @[toc]
    • 1、概述🐜
    • 2、环境配置🪲
    • 3、功能说明
    • 4、使用Heob分析qt 程序内存泄漏🦧
    • 5、使用Heob检测qt 程序野指针/内存越界👓
    • 6、使用Heob检测qt 程序空指针/throw抛出异常👕
    • 7、使用Heob检测qt 程序重复释放👗
    • 8、使用Heob检测qt 程序长生命周期式内存泄漏👙
    • 9、相关地址🐐

更多精彩内容
👉内容导航 👈
👉C++软件调试 👈

1、概述🐜

绝大部分的文章都说Heob是一个内存泄漏分析工具,其实Heob只是内存泄漏分析功能比较突出,实际上Heob可以分析很多内存问题。

Heob是一个Windows下检测缓冲区溢出(野指针、空指针、内存越界、重复释放、异常捕获等)和内存泄漏的工具,集成到Qt Creator中,功能强大,简单容易上手。

  • 支持MSVC和MinGW编译器编译的程序内存泄漏检测;

  • 支持32位和64位程序;

  • 不支持Linux;

  • 支持设置过滤内存泄漏字节大小;

  • 支持异常处理;

  • 支持与Qt调试器、事后调试器联动;

  • 支持将分析结果导出位xml文件,后续通过加载xml文件查看分析结果;

  • Qt Creator支持4.6以上版本,低版本没有这个功能,可以自行安装高版本的QtCreator(注意:不是Qt版本,是IDE版本)。

  • 处理速度块,占用资源少。

在Qt中使用Heob分析内存泄漏有4种用法:

  • 方法1: 使用Heob分析MSVC编译生成的程序,对于 PDB 调试信息,使用 dbghelp.dll,速度块;

  • 方法2: 使用Heob分析MinGW编译生成的程序, 对于DWARF 调试信息 (gcc) ,需要下载dwarfstack.dll库到Heob路径下才可以使用,性能会低很多;

在这里插入图片描述

  • 方法3: 使用Heob分析MinGW编译生成的程序,通过cv2pdb将DWARF 转成PDB进行分析,性能和分析MSVC编译的程序差不多。
  • 方法4: 命令行运行。

注意:

  • MSVC版本<=2017时,Heob检测会出现误报,将内存泄漏包位外部错误的内存泄漏,所以如果使用的编译器版本比较低,过滤设置时就需要勾选上外部错误 项;
  • 对MinGW和MSVC支持不同,有些情况使用MSVC编译器可以检测出来,使用MinGW检测不出来,有些情况相反。
  • 运行Heob前需要保证代码已经完成编译并生成了可执行程序。

演示环境:

环境版本
系统Windows11
开发环境Qt5.9、Qt5.12.12、Qt5.14.2、Qt6.8
IDEQt Creator 5、Qt Creator 10、Qt Creator 14、Qt Creator 15
编译器mingw730_64、mingw1310_64、MSVC2015-64、MSVC2017-64、MSVC2022-64
分析工具Heob 4.0
依赖库dwarfstack 2.2

2、环境配置🪲

  • 下载Heob 4.0和dwarfstack 2.2 解压到同一个文件夹中;

  • 打开Qt Creator,选中【分析】【Heob】;

在这里插入图片描述

  • 打开Heob窗口后点击【浏览】选择Heob路径,然后点击右下角图标保存配置。

    在这里插入图片描述

  • 创建一个Qt工程,测试代码如下所示

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}class Test
{
public:Test(){p = new int;}private:int* p;
};/*** @brief  内存泄漏1*/
void Widget::on_pushButton_clicked()
{Test* test = new Test();free(test);
}void fun()
{for(int i = 0; i < 1024; i++){int*p = new int[1000];qDebug() << p[1];}
}
/*** @brief 内存泄漏2*/
void Widget::on_pushButton_2_clicked()
{fun();
}/*** @brief 野指针1*/
void Widget::on_pushButton_3_clicked()
{int* p = new int;delete p;*p = 123;
}/*** @brief 野指针2*/
void Widget::on_pushButton_4_clicked()
{int* p;*p = 123;
}/*** @brief 空指针*/
void Widget::on_pushButton_5_clicked()
{int* p = nullptr;*p = 123;
}/*** @brief 内存越界*/
void Widget::on_pushButton_6_clicked()
{int*p = new int[12];p[123] = 123;p[12] = 1234;delete[] p;
}/*** @brief 重复释放*/
void Widget::on_pushButton_7_clicked()
{int*p = new int[12];p[1] = 123;delete[] p;delete[] p;
}/*** @brief 抛出异常*/
void Widget::on_pushButton_8_clicked()
{throw 123;
}/*** @brief 成员数组添加数据*/
void Widget::on_pushButton_9_clicked()
{for(int i = 0; i < 10000; i++){m_list.append(new int);qDebug() << i;}
}QList<int*> g_list;
/*** @brief 全局数组添加数据*/
void Widget::on_pushButton_10_clicked()
{for(int i = 0; i < 10000; i++){g_list.append(new int);qDebug() << i;}
}/*** @brief 释放内存*/
void Widget::on_pushButton_11_clicked()
{for(int i = 0; i < m_list.count(); i++){delete m_list[i];}for(int i = 0; i < g_list.count(); i++){delete g_list[i];}m_list.clear();g_list.clear();QMessageBox::about(this, "注意!", QString("已经释放内存:%1  %2").arg(m_list.count()).arg(g_list.count()));
}

在这里插入图片描述

3、功能说明

  • 详细功能说明可以打开命令行,使用heob.exe -H命令查看;

如图所示:

在这里插入图片描述

  • 点击【新建/删除】可以创建新的配置文件;

  • 点击右下角软盘图标可以保存配置,配置文件保存在C:\Users\MHF\AppData\Roaming\QtProject\QtCreator.ini文件中;

  • 点击【OK】开始进行分析。

  • Heob Path: 下载解压的Heob.exe文件路径;

  • XML output file: 生成的xml文件名称,使用的相对路径,在可执行程序路径下,后续可通过【调试】窗口中的文件夹图标加载生成的xml文件;

    在这里插入图片描述

  • Handle exceptions: 设置出现异常时的处理方式

    • 设置为On则使用Heob处理,出现异常时程序退出,在调试窗口显示出现异常的信息;
    • 设置为Off则在出现异常时,会使用事后调试器进行调试。
    • 设置为Only则禁用所有Heob功能,除了安装异常处理程序。如果应用程序崩溃,则只显示崩溃的堆栈跟踪,不检测内存泄漏。因此,当在控制台上使用Heob或为子进程运行Heob时,此选项非常有用。

    在这里插入图片描述

  • Run with debugger: 勾选上后会以Debug调试模式运行,当出现异常(例如空指针野指针)时会触发断点,定位到出现异常的位置;

在这里插入图片描述

  • Raise breakpoint exception on error: 表示出现异常时触发断点,(主要用于重复释放)
    • 如果没勾选,则出现重复释放内存越界等问题时,不会触发异常断点,会将检测结果写入文件;
    • 如果勾选上后,并且勾选了Run with debugger,则出现重复释放内存越界等问题时,将会触发异常断点;

在这里插入图片描述

  • Page protection: 这个功能更适合用于检测内存越界、野指针;
    • 选择OFF时更适合检测内存泄漏;
    • 选择After后会在分配的内存块末尾设置一个保护页,当访问到这个保护页时就会触发异常,从而识别出野指针、内存越界;
    • 选择Before则会再分配的内存块前设置一个保护页;
    • 这个功能会消耗内存、降低检查速度,建议仅用于64位或短时间运行的程序。

在这里插入图片描述

  • Freed memory protection: 这个功能会增加释放内存保护功能,已经释放的内存就不会再被使用,对于检测野指针、重复释放问题有用,但是会大量消耗内存。
  • Leak details: 这个选项用于设置程序退出时融合处理收集到的内存泄漏数据,不同的设置影响分析结果和处理速度;
    • None:表示不收集内存泄漏数据,所以退出时速度最快;
    • Simple:表示将所有未释放的内存写入结果文件,速度最慢,生成的xml文件也最大,所有内存泄漏分析结果都会被记录为16 bytes in 1 blocks are lost in loss record 196 of 209 (#2513),无法通过过滤器进行过滤;
    • Detect Leak Types:会记录所有确定的直接内存泄漏、间接内存泄漏到文件中,速度会快一些;
    • Detect Leak Types (Show Reachable):除了记录所有确定的直接内存泄漏、间接内存泄漏到文件中,还会将可能存在内存泄漏的结果记录到文件中,可以通过过滤器中【可能的内存泄漏】选项过滤;
    • Fuzzy Detect Leak Types:选择模糊检测泄漏类型来标记内存块,或者它们是否引用了任何地址。当使用一些自定义分配器(例如:ffmpeg的av_malloc())时,此选项很有用,检测结果最少,只保留最有可能内存泄漏的记录,速度快,生成的文件小;
    • Detect Leak Types (Show Reachable) :与Fuzzy Detect Leak Types类似,不过会将其它的记录认为是可能存在的内存泄漏,也会记录到文件中,可以通过过滤器中【可能的内存泄漏】选项过滤。

在这里插入图片描述

  • Minimum leak size: 设置记录内存泄漏的最小字节数,低于设置值的内存泄漏不会被记录;

在这里插入图片描述

  • Control leak recording: 控制记录内存泄漏的开关、记录时间段等,更加灵活的记录分析内存泄漏的功能(例如记一个数组不断添加堆内存数据,很长一段时间才会释放一次,这种就是特殊情况的内存泄漏,就可以通过n/f快捷键来控制检测);

    • OFF:关闭终端,始终开启内存泄漏记录;
    • On (Start Disabled):打开终端,Heob启动时不记录内存泄漏,可在终端中进行控制;
    • On (Start Enabled):打开终端,Heob启动时就开始记录内存泄漏,并且可在终端中进行控制。

    在这里插入图片描述

  • Extra arguments: 用于输入运行其它Heob参数,例如输入-vleaks.svg会将检测结果生成svg矢量图;

    • 更多Heob参数使用命令行Heob64.exe -H查看。

    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4、使用Heob分析qt 程序内存泄漏🦧

  1. 打开测试代码,使用MSVC编译器、Debug模式进行编译,保留pdb符号表;

  2. 编译生成可执行程序;

  3. 点击【分析】【Heob】【OK】启动程序进行分析;

  4. 当程序运行后分别点击【泄漏1】【泄漏2】按键,然后退出程序,程序退出后会将分析结果生成位leaks.xml文件,并在调试窗口显示检测到的内存泄漏;

  5. 生成的检测结果会有许多动态库中的误报,可以点击调试窗口上的过滤图标,取消勾选【外部错误】项(如果MSVC版本<=2017则勾选外部错误);

    在这里插入图片描述

  6. 检测结果如下所示,出现两个内存泄漏,大小分别是409600字节和16字节。

    在这里插入图片描述

    在这里插入图片描述

5、使用Heob检测qt 程序野指针/内存越界👓

  • 打开Heob窗口;
  • 将Page protection选为【After】或者【Before 】;
  • 点击开始检测,运行野指针代码就可以成功捕获到野指针异常。
  • 由于野指针、内存越界都是不可恢复的异常,所以检测到这类异常后会直接终止Heob。

在这里插入图片描述

6、使用Heob检测qt 程序空指针/throw抛出异常👕

  • 打开Heob窗口;
  • 使用默认设置;
  • 点击开始检测,运行野指针代码就可以成功捕获到空指针、抛出异常。
  • 由于空指针异常无法恢复,检测到后会终止Heob;
  • 如果throw抛出异常后没有被try捕获,则会被Heob检测到,并触发终止,如果被try捕获,则Heob无法检测。

在这里插入图片描述

7、使用Heob检测qt 程序重复释放👗

  • 打开Heob窗口;
  • 勾选Raise breakpoint exception on error: 表示出现异常时触发断点,如果不勾选就只会保存到检测结果;
  • 再勾选Run with debugger ,在出现重复释放异常时,就会触发断点,进入调试。

在这里插入图片描述

8、使用Heob检测qt 程序长生命周期式内存泄漏👙

这里的长生命周期式内存泄漏不同于普通内存泄漏使用new分配了而没有delete;

长生命周期内存泄漏指使用new分配了内存,过了很长时间才会delete,例如成员指针、全局变量、静态变量等;

这类内存泄漏会更加难以排查,也容易造成严重问题。

测试方法1: 无法检测到长生命周期内存泄漏

  • 打开Heob进行检测;
  • 点击按键,向成员数组中new大量变量;
  • 过一段时间后再释放成员数组中的所有内存;
  • 无法检测到出现内存泄漏;

在这里插入图片描述

测试方法1: 无法检测到长生命周期内存泄漏

  • 打开Heob窗口;

  • 如下图所示,选择Detect Leak Types(不必须),避免文件写入太多内存,检测大小设置为500字节(不必须),选择On(Start Disabled),在程序启动前不记录,在运行过程中通过终端命令行控制开始/结束记录的时机;

    在这里插入图片描述

  • 点击【OK】启动Heob;

  • 程序运行后按下n键开始记录;

  • 然后在程序中分别给成员数组、全局数组分配内存;

  • 在终端按下f键停止记录,并按下s键将当前内存泄漏分析结果写入文件

  • 然后点击按键释放数组分配的内存;

  • 退出程序后就可以看见检测到的内存泄漏了。

在这里插入图片描述

9、相关地址🐐

  • Heob
  • 下载dwarfstack.dll
  • 通过cv2pdb将DWARF 转成PDB
  • Heob | Qt Creator Documentation
  • Detect memory leaks with Heob | Qt Creator Documentation

相关文章:

C++(Qt)软件调试---内存分析工具Heob(26)

C(Qt)软件调试—内存分析工具Heob&#xff08;26&#xff09; 文章目录 C(Qt)软件调试---内存分析工具Heob&#xff08;26&#xff09;[toc]1、概述&#x1f41c;2、环境配置&#x1fab2;3、功能说明4、使用Heob分析qt 程序内存泄漏&#x1f9a7;5、使用Heob检测qt 程序野指针…...

Redis五大基本类型——String字符串命令详解(命令用法详解+思维导图详解)

目录 一、String字符串类型介绍 二、常见命令 1、SET 2、GET 3、MGET 4、MSET 使用MGET 和 使用多次GET的区别 5、DEL 6、SETNX SET、SET NX和SET XX执行流程 7、INCR 8、INCRBY 9、DECR 10、DECYBY 11、INCRBYFLOAT 12、APPEND 13、GETRANGE 14、SETRANGE …...

Flutter中的Material Theme完全指南:从入门到实战

Flutter作为一款热门的跨平台开发框架&#xff0c;其UI组件库Material Design深受开发者喜爱。本文将深入探讨Flutter Material Theme的使用&#xff0c;包括如何借助Material Theme Builder创建符合产品需求的主题风格。通过多个场景和代码实例&#xff0c;让你轻松掌握这一工…...

Python 第三方库 PyQt5 的安装

目录 前言 PyQt5安装 不同操作系统PyQt5安装 一、Windows 系统 二、macOS 系统 三、Linux 系统&#xff08;以 Ubuntu 为例&#xff09; 安装 PyQt5 可能会遇到的问题 一、环境相关问题 二、依赖问题 三、网络问题 四、安装工具问题 五、运行时问题 六、环境配置问…...

CSS基础也要进行模电实验

盒子阴影 圆角边框已经介绍过哩&#xff0c;现在先介绍一下盒子阴影的效果如何实现 CSS3中新增了盒子阴影&#xff0c;可以使用box-shadow属性为盒子添加阴影 这是固定的语法&#xff1a; text-shadow: h-shadow v-shadow blur color; 它有这些可选的值&#xff1a; 哦。 …...

贴代码框架PasteForm特性介绍之markdown和richtext

简介 PasteForm是贴代码推出的 “新一代CRUD” &#xff0c;基于ABPvNext&#xff0c;目的是通过对Dto的特性的标注&#xff0c;从而实现管理端的统一UI&#xff0c;借助于配套的PasteBuilder代码生成器&#xff0c;你可以快速的为自己的项目构建后台管理端&#xff01;目前管…...

3D Gaussian Splatting 代码层理解之Part3

最后,内容到达了高斯泼溅过程中最有趣的阶段:渲染!这一步可以说是最关键的,因为它决定了模型的真实性。然而,它也可能是最简单的。在本系列的Part 1和Part2,文章演示了如何将 Raw 3D椭球 转换为可渲染的格式,但现在我们实际上必须完成这项工作并渲染到一组固定的像素上。…...

Ceph 中PG与PGP的概述

在Ceph分布式存储系统中&#xff0c;PG&#xff08;Placement Group&#xff09;和PGP&#xff08;Placement Group for Placement purpose&#xff09;是两个至关重要的概念&#xff0c;它们共同决定了数据在集群中的分布和复制方式。以下是关于Ceph中PG和PGP关系的详细解释&a…...

已解决:spark代码中sqlContext.createDataframe空指针异常

这段代码是使用local模式运行spark代码。但是在获取了spark.sqlContext之后&#xff0c;用sqlContext将rdd算子转换为Dataframe的时候报错空指针异常 Exception in thread "main" org.apache.spark.sql.AnalysisException: java.lang.RuntimeException: java.lang.Nu…...

flutter字体大小切换案例 小字体,标准字体,大字体,超大字体案例

flutter字体大小切换案例 小字体&#xff0c;标准字体&#xff0c;大字体&#xff0c;超大字体案例 Android iOS设备带有选择记录 我的flutter项目版本 environment: sdk: ‘>3.4.4 <4.0.0’ 图片案例 pubspec.yaml 添加依赖 # 屏幕尺寸适配 https://github.com/OpenF…...

智慧建造-运用Trimble技术将梦幻水族馆变为现实【上海沪敖3D】

项目概述 西雅图水族馆耗资1.6亿美元对海洋馆进行扩建。该项目包括建造三个大型栖息地&#xff0c;每个建筑物几乎都没有直边&#xff0c;其中一个主栖息地由520立方米混凝土和355吨钢筋组成。特纳建筑公司的混凝土团队通过强大的贸易合作伙伴和创新的数字制造技术&#xff0c;…...

【NOIP提高组】计算系数

【NOIP提高组】计算系数 C语言实现C实现Java实现Python实现 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给定一个多项式 (ax by)^k &#xff0c;请求出多项式展开后 x^n y^m 项的系数。 输入 共一行&#xff0c;包含 5 个整数&#x…...

IDEA部署AI代写插件

前言 Hello大家好&#xff0c;当下是AI盛行的时代&#xff0c;好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风&#xff0c;然后写实什么的&#xff0c;现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…...

【阅读记录-章节1】Build a Large Language Model (From Scratch)

目录 1. Understanding large language models1.1 What is an LLM?补充介绍人工智能、机器学习和深度学习的关系机器学习 vs 深度学习传统机器学习 vs 深度学习&#xff08;以垃圾邮件分类为例&#xff09; 1.2 Applications of LLMs1.3 Stages of building and using LLMs1.4…...

微服务day08

Elasticsearch 需要安装elasticsearch和Kibana&#xff0c;应为Kibana中有一套控制台可以方便的进行操作。 安装elasticsearch 使用docker命令安装&#xff1a; docker run -d \ --name es \-e "ES_JAVA_OPTS-Xms512m -Xmx512m" \ //设置他的运行内存空间&#x…...

JAVA接入WebScoket行情接口

Java脚好用的库很多&#xff0c;开发效率一点不输Python。如果是日内策略&#xff0c;需要更实时的行情数据&#xff0c;不然策略滑点太大&#xff0c;容易跑偏结果。 之前爬行情网站提供的level1行情接口&#xff0c;实测平均更新延迟达到了6秒&#xff0c;超过10只股票并发请…...

使用Axios函数库进行网络请求的使用指南

目录 前言1. 什么是Axios2. Axios的引入方式2.1 通过CDN直接引入2.2 在模块化项目中引入 3. 使用Axios发送请求3.1 GET请求3.2 POST请求 4. Axios请求方式别名5. 使用Axios创建实例5.1 创建Axios实例5.2 使用实例发送请求 6. 使用async/await简化异步请求6.1 获取所有文章数据6…...

Vue2+ElementUI:用计算属性实现搜索框功能

前言&#xff1a; 本文代码使用vue2element UI。 输入框搜索的功能&#xff0c;可以在前端通过计算属性过滤实现&#xff0c;也可以调用后端写好的接口。本文介绍的是通过计算属性对表格数据实时过滤&#xff0c;后附完整代码&#xff0c;代码中提供的是死数据&#xff0c;可…...

抖音热门素材去哪找?优质抖音视频素材网站推荐!

是不是和我一样&#xff0c;刷抖音刷到停不下来&#xff1f;越来越多的朋友希望在抖音上创作出爆款视频&#xff0c;但苦于没有好素材。今天就来推荐几个超级实用的抖音视频素材网站&#xff0c;让你的视频内容立刻变得高大上&#xff01;这篇满是干货&#xff0c;直接上重点&a…...

spring-cache concurrentHashMap 自定义过期时间

1.自定义实现缓存构建工厂 import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap;import lombok.Getter; import lombok.Setter; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001

qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类&#xff0c;直接把源文件拖进VS的项目里&#xff0c;然后VS卡住十秒&#xff0c;然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分&#xff0c;导致编译的时候找不到了。因…...