04-常见内存错误以及valgrind使用
代码段:
只读数据,因此对这一部分的数据,试图写只读数据,这个在编译的时候基本上可以检测。
数据段/BSS段:
未初始化直接访问,即使没有显示初始化,仍然会初始化为0
栈空间数据:
(1)局部变量,未初始化变量会给随机的初值,出现异常情况更诡异
(2)栈溢出:在栈中申请过大的局部变量
堆空间数据
内存泄露 (1)申请未释放(2)申请后,双重释放
对于所有的地址空间:
(1) 野指针的问题:未初始化指针,会访问这个指针指向的空间
(2) 越界访问:例如一个数据a[10] ,试图访问啊a【10】以及以后数据
(3) 非法的越权访问 例如:mmap的空间只读,但试图写
(4) 空间不在控制范围仍然去访问空间,例如返回局部变量地址,且后面访问这个空间
虽然在编程时尽量避免这些问题,但是一旦出现问题,要善于使用工具去检测我们的内存错误
可以使用工具
$Sudo apt-get install valgrind
$ valgrind --tool=memcheck--show-reachable=yes --read-var-info=yes --verbose --time-stamp=yes --leak-check=full--log-file=mycode.log ./valgrind_example01
如果要使用图形化的工具,需要安装QT 这个工具名字叫 Valkyrie 第一、自己在编程中,要避免一些常见的错误,第二、要善于使用工具去检测我们的内存错误。 测试例子:
[email protected]:~/wangyiStudy# lsvalgrind_example01.c[email protected]:~/wangyiStudy#gcc -g -o valgrind_example01 valgrind_example01.c[email protected]:~/wangyiStudy# lsvalgrind_example01 valgrind_example01.c[email protected]:~/wangyiStudy#valgrind --tool=memcheck --show-reachable=yes --read-var-info=yes --verbose--time-stamp=yes --leak-check=full --log-file=mycode.log ./valgrind_example01[email protected]:~/wangyiStudy# lsmycode.log valgrind_example01 valgrind_example01.c
测试程序代码:valgrind_example01.c
[email protected]: # morevalgrind_example01.c#include<stdio.h>#include<stdlib.h>intmain(void){int i[5];if(i[0] == 0)i[1] = 1;char *ptr1;*ptr1 = ‘c‘;char *ptr = malloc(100);free(ptr);free(ptr);return 0;}
查看生成的日志:
[email protected]:~/wangyiStudy# moremycode.log
==00:00:00:03.1165282== HEAP SUMMARY:
==00:00:00:03.1165282== in use at exit: 0 bytes in 0blocks
==00:00:00:03.1165282== totalheap usage: 1 allocs, 2 frees, 100 bytes allocated //一次申请,双重释放
==00:00:00:03.1165282==
==00:00:00:03.1165282== All heap blocks were freed -- no leaks are possible
==00:00:00:03.1165282==
==00:00:00:03.1165282== Use --track-origins=yes to see where uninitialised values come from
==00:00:00:03.1165282== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
==00:00:00:03.1165282==
==00:00:00:03.1165282== 1 errors in context 1 of 3:
==00:00:00:03.1165282== Invalid free() / delete / delete[] / realloc()
==00:00:00:03.1165282== at 0x4C2BDEC: free (in/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:00:03.1165282== by 0x4005BF: main(valgrind_example01.c:15)
==00:00:00:03.1165282== Address 0x51fd040 is 0 bytes insidea block of size 100 free‘d
==00:00:00:03.1165282== at 0x4C2BDEC: free (in/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:00:03.1165282== by 0x4005B3: main(valgrind_example01.c:14)
==00:00:00:03.1165282==
==00:00:00:03.1165282==
==00:00:00:03.1165282== 1 errors in context 2 of 3:
==00:00:00:03.1165282== Use of uninitialised value of size 8
==00:00:00:03.1165282== at 0x400597: main(valgrind_example01.c:11)
==00:00:00:03.1165282==
==00:00:00:03.1165282==
==00:00:00:03.1165282== 1 errors in context 3 of 3:
==00:00:00:03.1165282== Conditional jump or move depends on
uninitialised value(s) //未初始化==00:00:00:03.1165282== at 0x40058A: main (valgrind_example01.c:8) // 错误定位
==00:00:00:03.1165282==
==00:00:00:03.1165282== ERROR SUMMARY: 3 errors from 3 contexts(suppressed: 0 from 0) // 总计 3 出错误