1. 程式人生 > >C/C++程序調試和內存檢測

C/C++程序調試和內存檢測

trace 錯誤 1.5 ifd 排除 sid 我們 pos ces

程序出現錯誤很正常,一個優秀的程序員必須學會調試,發現錯誤並改正。減少程序錯誤最有效的方法是:在敲代碼之前,多花點時間思考,如何構造程序,數據結構和算法,盡量把細節提前寫下來,可以嘗試著在紙上寫出核心代碼,這樣可以減少今後修改代碼的時間。
創一個小群,供大家學習交流聊天
如果有對學C++方面有什麽疑惑問題的,或者有什麽想說的想聊的大家可以一起交流學習一起進步呀。
也希望大家對學C++能夠持之以恒
C++愛好群,
如果你想要學好C++最好加入一個組織,這樣大家學習的話就比較方便,還能夠共同交流和分享資料,給你推薦一個學習的組織:快樂學習C++組織 可以點擊組織二字,可以直達請添加鏈接描述
技術分享圖片
1、常用的調試技巧


(1)代碼檢查,重新閱讀程序,排除比較明顯的錯誤。編譯時帶上-Wall參數,生成所有的警告信息。

gcc -Wall -pedantic -ansi 表示以ansi/iso生成所有的警告西信息。

(2)取樣法:在程序中增加一些代碼,收集更多與程序運行時的行為相關的信息。使用條件編譯,可以清楚的辨別哪些是調試代碼,有利於調試後的代碼整理。

例如:

#ifdef DEBUG
 std::cout << x :
#endif

程序編譯時可以選擇性的加上-DDEBUG。如果加上這個標誌,就定義了DEBUG這個符號,從而在程序中包含調試用的額外代碼,沒有加上該標誌,這些調試代碼將刪除。

(3)程序的受控執行。用調試器來控制代碼的運行,隨時查看這些變量的狀態。

為了能夠調試程序,需要在編譯和鏈接時為每個源文件加上編譯選項參數。這些選項的作用是讓編譯器在程序中添加額外的調試信息。這些信息包括符號和源代碼行號,調試器將利用這些信息向用戶顯示程序已經執行到的源代碼的位置。-g標誌是對程序調試性編譯時常用的一個選項。調試信息的加入使可執行程序的長度成倍的增長、容量增加,程序運行時的內存數量還是和原來一樣,程序調試結束後,最好還是將調試信息從程序的發行版中刪除。
2、使用gdb進行程序調試

常用功能命令:

g++ -g -o test test.cpp //編譯時加上-g參數

1、啟動gdb: gdb test
2、help
3、具備帶有歷史記錄的命令行編輯功能,方向鍵選擇之前執行過的命令,直接回車鍵再次執行最近執行過的那條命令。單步調試非常有用。

4、quit:退出
5、run:執行這個程序,程序運行失敗時gdb會報告失敗的原因和位置。
6、backtrace(bt):棧跟蹤,失敗時停止的位置,幫助我們找到程序到達錯誤地點的路徑。
7、print:run 後檢查變量,註意變量的生命期。
8、打印圍繞當前位置前後的一段代碼,繼續使用list可以顯示更多的代碼。
9、設置斷點,停止程序的運行,查看變量。help breakpoint,break lineNumber,cont,end,display,disable breakpoint number,clear,commands breakpointNumber.
10、設置斷點後經常使用單步調試命令next(n),查看程序運行的細節。
3、valgrind內存調試

動態內存分配很容易出現程序漏洞,必須清楚自己分配的每一塊內存,而且要確定沒有使用已經釋放的內存塊,非常重要。內存調試的工具有很多,這裏使用的是valgrind工具。在centos 7中直接使用 yum install valgrind 安裝。

#include <iostream>

int main()
{
int *ptr = new int [3];
ptr[3]=1;

delete [] ptr;
std::cout << ptr[1];
return 0;

}

上面簡單的代碼編譯運行不會發生錯誤,但是實際上發生了很嚴重的內存問題。ptr[3]訪問越界,std::cout <<ptr[i],讀已經釋放過的內存。

通過valgrind工具可以檢查出來:

[xgwang@localhost Desktop]$ g++ -g -o test2 test2.cpp
[xgwang@localhost Desktop]$ valgrind ./test2
==21739== Memcheck, a memory error detector
==21739== Copyright (C) 2002-2013, and GNU GPL‘d, by Julian Seward et al.
==21739== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==21739== Command: ./test2
==21739==
==21739== Invalid write of size 4
==21739== at 0x40081E: main (test2.cpp:8)
==21739== Address 0x5a1504c is 0 bytes after a block of size 12 alloc‘d
==21739== at 0x4C2A7AA: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==21739== by 0x400811: main (test2.cpp:7)
==21739==
==21739== Invalid read of size 4
==21739== at 0x40083F: main (test2.cpp:11)
==21739== Address 0x5a15044 is 4 bytes inside a block of size 12 free‘d
==21739== at 0x4C2B5E1: operator delete (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==21739== by 0x400836: main (test2.cpp:10)
==21739==
0==21739==
==21739== HEAP SUMMARY:
==21739== in use at exit: 0 bytes in 0 blocks
==21739== total heap usage: 1 allocs, 1 frees, 12 bytes allocated
==21739==
==21739== All heap blocks were freed -- no leaks are possible
==21739==
==21739== For counts of detected and suppressed errors, rerun with: -v
==21739== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

C/C++程序調試和內存檢測