Qt内存管理及泄露后定位到内存泄漏位置的方法

Qt内存管理机制

Qt使用对象父子关系进行内存管理。在创建类的对象时,为对象指定父对象指针。当父对象在某一时刻被销毁释放时,父对象会先遍历其所有的子对象,并逐个将子对象销毁释放。

Qt内存管理代码示例

QLabel *label = new QLabel;

这里是自己在源码中新建的label控件,没有指定父对象,需要自己手动释放内存,不释放会有内存泄漏。

QLabel *label = new QLabel();

这里是自己在源码中新建的label控件,执行了QLabel的构造函数,没有指定父对象,需要自己手动释放内存,不释放会有内存泄漏。

QLabel *label = new QLabel;
label->setParent(this);

设定了父对象,不仅可以显示在父窗口,还可以自动帮助释放内存

QStandardItemModel *itemModel = new QStandardItemModel;
ui.tableView->setModel(itemModel);

这里只是设置了model,ui控件不是model的父对象,无法帮助itemModel释放内存;

QStandardItem *item = new QStandardItem;
itemModel->setItem(1,item);
itemModel->clear();

这里model做了clear操作,会帮助释放model下item占用的内存,没有释放model的内存;

MyWidget *myWidget = new MyWidget;

自己创建的界面也要自己手动释放内存空间;

Qt定位到内存泄漏位置的方法

Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具。使用VLD可以检测到内存泄漏的位置。VLD支持MSVC编译器,不支持MingGW编译器。VLD的使用方法:
从这里下载,下载后可以看到VLD的include文件,lib文件,不需要从网上下载exe了。
VLD内存泄漏检测编程文件,包含头文件,库文件,配置文件

使用方法

在项目文件内,添加相应的include文件和lib文件,具体步骤不再详解。
1.在头文件内添加

#include "vld.h"

2.在生成的exe文件同级目录下放置vld.ini
在这里插入图片描述

vld.ini是VLD的配置文本,默认读取的是安装目录下的vld.ini 文件,当exe所在目录下也有vld.ini文件时会优先读取这份配置。

vld.ini参数设置说明
默认读取的是安装目录下的vld.ini 文件,当exe所在目录下也有vld.ini文件时会优先读取这份配置。

VLD:选择VLD的打开与关闭。在Debug模式下运行,关闭以后会有一行
VLD关闭的提示信息。默认为 on。

AggregateDuplicates:设置为 yes 时,相同地方产生内存泄漏只输
出一次,但是会统计发生的次数。默认是 no 。

MaxDataDump:输出的dump数据个数,默认为 256。

MaxTraceFrames:输出的调用栈的层数。默认是 64。

ReportEncoding :report 文件的编码格式,可选有 
ascii, unicode,默认是 ascii 。

ReportFile :report 文件的路径。默认是
 “.\memory_leak_report.txt”

ReportTo :可选有 debugger, file, both,debugger 
表示输出到 debug模式下的输出窗口;file 表示只输出到文件中;
 both顾名思义,全都都输出。默认是 debugger 。

打开exe,操作结束以后,关闭exe,可以看到VLD的报告,报告中包含了几个内容:

【Block X at …: Y bytes】:第X个块(new)泄漏了Y个字节;

【Call Stack】泄漏内存的堆栈信息,对应的行便是具体的代码位置;

【Data】泄漏内存的数据信息;

【Visual Leak Detector detected X memory leak (Y bytes).】总共 X 处泄漏,共泄漏字节数 Y 字节;

在这里插入图片描述

一些遇到的问题及解决方案

出现call stack(TID)后面无函数定位,比如:
在这里插入图片描述
只需要修改ini文件中ReportEncoding = ascii,ascii为unicode即可,再次执行程序后便可以看到源码定位泄漏位置;
在这里插入图片描述
要在release模式下使用VLD,必须在头文件vld.h之前预定于宏(参考 VLD Issues 46)

#define VLD_FORCE_ENABLE
#include "vld.h"

猜你喜欢

转载自blog.csdn.net/qq_43376782/article/details/130194324
今日推荐