Qt使用Valgrind分析内存泄漏

发布时间:2024-01-23 18:00

目录

  • Valgrind安装和使用
  • 使用了不匹配的方式释放内存
  • 重复释放
  • 未释放内存
  • 使用和释放未分配内存的野指针
  • 使用已释放的野指针
  • 数组越界访问

Valgrind安装和使用

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

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

QT自带Valgrind工具,工程编译好以后,在QT菜单栏–Analyze–Valgrind内存分析器,点击以内存分析(Memcheck)模式启动程序,程序运行一段时间关闭,Memcheck会记录内存异常列表,包含报错信息和简单调用栈。
Qt使用Valgrind分析内存泄漏_第1张图片

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

代码示例,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

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号