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
第一、自己在編程中,要避免一些常見的錯誤,第二、要善於使用工具去檢測我們的內存錯誤。
測試例子:
root@ubuntu:~/wangyiStudy# ls
valgrind_example01.c
root@ubuntu:~/wangyiStudy#gcc -g -o valgrind_example01 valgrind_example01.c
root@ubuntu:~/wangyiStudy# ls
valgrind_example01 valgrind_example01.c
root@ubuntu:~/wangyiStudy#valgrind --tool=memcheck --show-reachable=yes --read-var-info=yes --verbose--time-stamp=yes --leak-check=full --log-file=mycode.log ./valgrind_example01
root@ubuntu:~/wangyiStudy# ls
mycode.log valgrind_example01 valgrind_example01.c
測試程序代碼:valgrind_example01.c
root@ubuntu: # morevalgrind_example01.c
#include<stdio.h>
#include<stdlib.h>
int
main(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;
}
查看生成的日誌:
root@ubuntu:~/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 出錯誤