Qt使用Valgrind分析内存泄漏

Valgrind是一款Linux下的内存调试和性能分析工具,用于检测内存泄漏、不匹配的内存释放、重复释放、未释放内存、野指针等问题。文章通过实例展示了如何使用Valgrind的Memcheck工具,以及解释了各种常见的内存错误类型及其可能导致的后果。通过QT集成Valgrind,可以方便地在开发过程中进行内存分析,帮助开发者定位和修复内存管理问题。
摘要由CSDN通过智能技术生成

Valgrind安装和使用

Valgrind是linux下一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具包,包含七个工具。
我们使用其中的Memcheck来检测程序中出现的内存问题。

sudo apt-get install valgrind#安装
valgrind --version#查看版本

QT集成了Valgrind工具,工程编译好以后,在QT菜单栏–Analyze–Valgrind内存分析器,点击以内存分析(Memcheck)模式启动程序,程序运行一段时间关闭,Memcheck会记录内存异常列表,包含报错信息和简单调用栈。
在这里插入图片描述

使用了不匹配的方式释放内存

代码示例,new出来的要用delete释放,malloc出来的要用free释放,new出来的数组要用delete []释放。

//示例a
    int lena = 10;
    int* pa = new int[lena];
    delete pa;//Mismatched free() / delete / delete [],应该使用 delete [] pa;

//示例b
    int* pb = new int;
    free(pb);//Mismatched free() / delete / delete [],应该使用delete pc;

//示例c
    char *pc;
    int lenc = 10;
    pc = (char *) malloc(lenc);
    delete pc;//Mismatched free() / delete / delete [],应该使用free(pd);

Memcheck错误信息,大意为使用了不匹配的释放方式,出错所在源文件,多少行等

Mismatched free() / delete / delete []MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:141: operator delete(void*) in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:14
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Address 0x10b225e0 is 0 bytes inside a block of size 40 alloc'd  1: operator new[](unsigned long) in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:13
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9

重复释放

    char *pd;
    int lend = 10;
    pd = (char *) malloc(lend);
    free(pd);
    free(pd);//Invalid free() / delete / delete[] / realloc(),重复释放

Memcheck错误信息,无效的释放

Invalid free() / delete / delete[] / realloc()MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:281: free in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:28
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Address 0x10b23650 is 0 bytes inside a block of size 10 free'd  1: free in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:27
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Block was alloc'd at  1: malloc in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:26
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9

未释放内存

    int lene = 20;
    //80 bytes in 1 blocks are definitely lost in loss record 6,814 of 8,736
    int* pe = new int[lene];//没有释放,应该使用 delete [] pb;

Memcheck错误信息,大意为在一个块中有80个字节(20个int)肯定会丢失,new或malloc了内存,但是没有delete或free。

80 bytes in 1 blocks are definitely lost in loss record 6,820 of 8,741MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:311: operator new[](unsigned long) in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:31
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9

使用和释放未分配内存的野指针

    char* pf;
    printf("pf=%s\n",pf);//Use of uninitialised value of size 8,使用了未分配内存的野指针
    free(pf);//Conditional jump or move depends on uninitialised value(s),Invalid free() / delete / delete[] / realloc(),释放了未分配内存的野指针

1、使用了未分配内存的野指针

Use of uninitialised value of size 8,使用了未初始化的值
  在 MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:341: strlen in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: __vfprintf_internal in ./stdio-common/vfprintf-internal.c:1647
  3: buffered_vfprintf in ./stdio-common/vfprintf-internal.c:2295
  4: printf in ./stdio-common/printf.c:33
  5: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:34
  6: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Uninitialised value was created by a stack allocation  1: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:6

2、释放了未分配内存的野指针
Conditional jump or move depends on uninitialised value(s),条件跳转或移动依赖于未初始化的值

Conditional jump or move depends on uninitialised value(s)MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:351: free in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:35
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Uninitialised value was created by a stack allocation  1: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:6

Invalid free() / delete / delete[] / realloc(),无效的释放

Invalid free() / delete / delete[] / realloc()MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:35中
Address 0x65cd6c0 is 0 bytes inside data symbol "_IO_2_1_stdout_"  1: free in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:35
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9

使用已释放的野指针

    int* pg;
    pg = new int;
    *pg=5;
    delete pg;
    printf("pg=%d\n",*pg);//Invalid read of size 4,pg已释放变成野指针,此处读取野指针

Memcheck错误信息,无效的读取,4个字节

Invalid read of size 4MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:411: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:41
  2: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Address 0x10b1b020 is 0 bytes inside a block of size 4 free'd  1: operator delete(void*) in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:40
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Block was alloc'd at  1: operator new(unsigned long) in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:38
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9

数组越界访问

    int *ph = (int*)malloc(5*sizeof(int));
    memset(ph,0,5*sizeof(int));
    printf("ph[5] = %d\n",ph[5]);//Invalid read of size 4,数组越界访问
    free(ph);

Memcheck错误信息,无效的读取,4个字节

Invalid read of size 4MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:451: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:45
  2: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9
Address 0x10b1b084 is 0 bytes after a block of size 20 alloc'd  1: malloc in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so
  2: MainWindow::MainWindow(QWidget*) in /home/chw/testCode/testValgring/testValgring/mainwindow.cpp:43
  3: main in /home/chw/testCode/testValgring/testValgring/main.cpp:9

要在Qt Creator中使用Valgrind进行内存泄漏检测和性能分析,可以按照以下步骤进行操作: 1. 首先,确保你已经安装了Valgrind。你可以在终端中运行`valgrind --version`来检查是否已安装。 2. 打开Qt Creator,并导航到你的项目。 3. 在Qt Creator的左侧窗格中,点击“项目”以打开项目视图。 4. 在项目视图中,选择你的项目名称。 5. 在右侧窗格中,选择“构建和运行”选项卡。 6. 在构建和运行选项卡中,展开“运行步骤”。 7. 点击“添加运行步骤”按钮,并选择“自定义进程步骤”。 8. 在自定义进程步骤中,将“命令”字段设置为Valgrind可执行文件的路径。例如,在大多数Linux系统上,Valgrind可执行文件的路径是`/usr/bin/valgrind`。 9. 将“参数”字段设置为你想要传递给Valgrind的参数。例如,如果你想使用Valgrind进行内存泄漏检测,你可以将参数设置为`--leak-check=full`。 10. 点击“应用”按钮以保存设置。 11. 现在,你可以点击Qt Creator工具栏上的绿色三角形按钮来启动应用程序并使用Valgrind进行分析。 请注意,Valgrind使用可能会对应用程序的性能产生一定影响,因此在进行性能分析时,建议使用一个更小规模的测试数据集来获得准确的结果。此外,在Valgrind分析期间,可能会产生大量的输出信息,所以确保你的终端或Qt Creator的输出窗口足够大来显示这些信息。 希望这些步骤可以帮助你在Qt Creator中使用Valgrind进行内存泄漏检测和性能分析
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值