• C 语言学习——Valgrind 内存问题简述


    作者:spch2008 
    来源:CSDN 
    原文:https://blog.csdn.net/spch2008/article/details/51375407 

    参数配置

    gcc

    • -g : 增加调试信息,供 valgrind 精准定位。
    • -oo : 关闭 gcc 优,优化产生的代码可能会造成 valgring 误判。

    valgrind

    --leak-check = full

    no : 不进行内存泄漏检测;yes : 显示内存泄漏情况;full : 显示内存泄漏和出错代码;

    --show-reachable = yes

    详细显示 still reachable 和 indirectly lost 两种类型的内心泄漏,默认不显示;、

    内存泄漏

    内存泄漏 : 由于疏忽和错误造成程序未能释放已经不能再使用的内存。

    泄漏类型

    possibly lost : 指针指向内存的内存位置

    still reachable : 程序运行结束后,内存没有释放,仍然可以访问。

    definitely lost:内存无法访问

    indirectly lost:虽然有地址指向该空间,但是无法访问

    泄漏举例
                Pointer  chain                 AAA Leak Case         BBB Leak Case
         ------------------------------       ---------------        -------------
    (1) RRR ----------------------> BBB                              DR
    (2) RRR -------> AAA ---------> BBB          DR                  IR
    (3) RRR                         BBB                              DL
    (4) RRR          AAA ---------> BBB          DL                  IL
    (5) RRR ----------?-----------> BBB                              (y)DR, (n)DL
    (6) RRR -------> AAA ----?----> BBB          DR                  (y)IR, (n)DL
    (7) RRR ---?---> AAA ---------> BBB          (y)DR, (n)DL        (y)IR, (n)IL
    (8) RRR ---?---> AAA ----?----> BBB          (y)DR, (n)DL        (y,y)IR, (n,y)IL, (_,n)DL
    (9) RRR          AAA ----?----> BBB          DL                  (y)IL, (n)DL
    
    Pointer chain legend:
    - RRR: a root set node or DR block
    - AAA, BBB: heap blocks
    - --->: a start-pointer
    - -?->: an interior-pointer
    
    Leak Case legend:
    - DR: Directly reachable
    - IR: Indirectly reachable
    - DL: Directly lost
    - IL: Indirectly lost
    - (y)XY: it's XY if the interior-pointer is a real pointer
    - (n)XY: it's XY if the interior-pointer is not a real pointer
    - (_)XY: it's XY in either case

    case 1:RRR  ----> BBB

    void *RRR;
    int main()
    {
      RRR = malloc(8);
      return 0;
    }

    ==1244== LEAK SUMMARY:

    ==1244==   still reachable : 8 bytes in blocks

    cas2 :RRR ----> AAA ----> BBB

    void **RRR;
    int main()
    {
            RRR = (void **)malloc(8); 
            *RRR = malloc(8); 
            return 0;    
    }

    ==1345== LEAK SUMMARY:

    ==1345==     still reachable: 16 bytes in 2 blocks

     

    case 3:RRR          BBB

    int main()
    {
            void *RRR = malloc(8);
            return 0;
    }

    ==1400== LEAK SUMMARY:

    ==1400==     definitely lost: 8 bytes in 1 blocks

    case4: RRR           AAA  ------> BBB

    int main()
    {
             void **RRR = (void**)malloc(8);
             *RRR = malloc(8);
             return 0;
    }

    ==1461== LEAK SUMMARY:

    ==1461==     definitely lost: 8 bytes in 1 blocks;

    ==1461==     indirectly lost: 8 bytes in 1 blocks;

    case 5: RRR   ----?-----> BBB

    void *RRR;
    int main()
    {
            RRR = malloc(8);
            RRR = (char *)RRR + 2;
            return 0;
    }

    ==1530== LEAK SUMMARY:

    ==1530==      possibly lost: 8bytes in 1 blocks;

    case6: RRR -----> AAA ---?---> BBB

    void **RRR;
    int main()
    {
            RRR = (void**)malloc(8);
            *RRR = malloc(8);
            *RRR = (char *)(*RRR) + 2;
            return 0;
    }

    ==1587== LEAK SUMMARAY;

    ==1587==     possibly  lost: 8 bytes in 1 blocks;

    ==1587==     still reachable: 8 bytes in 1 blocks;

    case 7: RRR ---?---> AAA ----> BBB

    void **RRR;
    int main()
    {
            RRR = (void **)malloc(8);
            *RRR = malloc(8);
             RRR = (void **)((char *)RRR + 1);
            
             return 0;  
    }

    ==1642== LEAK SUMMARY:

    ==1642==     possibly lost: 16 bytes in 2 blocks;

    case8: RRR ---?---> AAA ---?---> BBB

    void **RRR;
    int main()
    {
            RRR = (void **)malloc(8);
            *RRR = malloc(8);
    
            *RRR = ((char*)(*RRR) + 1);
            RRR = (void**)((char*)RRR + 1);
     
            return 0;
    }    

    ==1776== LEAK SUMMARY:

    ==1776==     possibly lost: 16 bytes in 2 blocks;

    case 9:RRR          AAA ---?---> BBB

    int main()
    {
           void **RRR = (void**)malloc(8);
           *RRR = malloc(8);
    
           *RRR = ((char*)(*RRR) + 1);
    
           return 0;
    }

    ==3856== LEAK SUMMARY:

    ==3856==     definitely lost: 8 bytes in 1 blocks;

    ==3856==     indirectly lost: 8 bytes in 1 blocks;

    内存错误

    读写越界

    int *arr = new int[2];
    arr[2] = 2;
    arr[0] = arr[2];
    
    delete [] arr;

    ==2371== Invalid write of size 4

    ==2371==     at 0x80485FD: main(test.c:2)

    ==2371==

    ==2371== Invalid write of size 4

    ==2371==     at 0x8048607: main(test.c:3)

    注意: 如果在栈空间上申请数组 arr ,valgrind 则检测不出读写越界

    地址重叠

    char *str = new char[10];
    char *src =  str;
    char *dst = str + 2;
    memcpy(dst, src, 4);
    
    delete [] str;

    ==2413== Source and destination overlap in memcpy(0x4339902a, 0x4339028, 4)

    ==2413===    at 0x402EE13: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.s0)

    ==2413==      by 0x8048654: main(test.c:4)

    多次释放

    char *str = new char[10];
    char *rep = str;
    
    delete[] str;
    delete[] rep;

    ==2440== Invalid free() / delete / delete[] / realloc()

    ==2440==     at 0x402BD38: operator delete

    ==2440==     by 0x8048623: main (test.c:5) 

    ==2440== Address 0x4339028 is 0 bytes inside a block of size 10 free 

    ==2440==      at 0x402BD38: operator delete

    ==2440==      by 0x8048610: main (test.c:4)

    ==2440== HEAP SUMMARY:

    ==2440==       in use ar exit: 0 bytest in 0 blocks

    ==2440==       total heap usage: 1 allocs, 2  frees , 10 bytes allocated

    释放内部指针

    int main()
    {
            void *RRR = malloc(10);
            RRR = (char *)RRR + 1;
    
            free(RRR);
            return 0;
    }

    ==3953== HEAP SUMMARy:

    ==3953== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1

    ==3953==       at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)

    ==3953==       by 0x804861: main(test.c:6)

    ==3953==

    ==3953== LEAK SUMMARY:

    ==3953==       definitely  lost: 10 bytes in 1 blocks

    分配与释放函数不一致

    int *arr= new int[10];
    
    free(arr);

    ==2519== Mismatched free() / delete / delete[]

    ==2519==      at 0x402B3D8: free

    ==2519==      by 0x8048601: main(test.c:3)

    ==2519== Address 0x4339028 is 0 bytes inside a block of size 40 alloc

    ==2519==       at 0x402ADFC: operator new

    ==2519==       by 0x80485F1: main (test.c:1)

    原理简述

    valgrind memcheck 在内部模拟一个 CPU 环境,所有的数据处理流程都在内部CPU进行模拟。

  • 相关阅读:
    HDU 3695 Computer Virus on Planet Pandora
    codeforces 706D Vasiliy's Multiset
    HDU 2222 Keywords Search
    POJ 2348 Euclid's Game
    HDU 1079 Calendar Game
    js选项卡的实现方法
    实现鼠标悬浮切换标题和内容
    js实现鼠标悬浮切换 setTab 代码实现
    自学Node.js: WebStorm+Node.js开发环境的配置
    windows 下安装nodejs
  • 原文地址:https://www.cnblogs.com/xushuhai/p/10775252.html
Copyright © 2020-2023  润新知