(三十二)單步除錯技術
編譯錯誤與執行錯誤
-
編譯錯誤:編譯器提示的錯誤,低階錯誤,語法有錯,根本無法生成exe檔案
-
執行錯誤:程式執行的結果與預期不一致,說明程式不對,存在bug,需要修改
一般情況下,能復現的錯誤都是可以解決的
單步除錯
單步除錯就是在要除錯的程式碼段首行加斷點,走一步看一下結果,邊走邊觀察,直到發現有哪一步走錯了
在vs環境下,斷點F9,單步F10,(F10是逐過程stepover,跳過函式具體執行,F11是逐語句stepinto,可以進入函式)開始除錯F5,再按F5跳到下一個斷點,若無下一個斷點則退出除錯。黃色箭頭表示即將執行這條語句
//求和 #include<stdio.h> int sum(int* buf,int n) { int total = 0; for(int i=0;i<total;i++) { total+=buf[i]; } return total; } int main() { int buf[64]; for(int i=0;i<64;i++) { buf[i]=i; } int result = sum(buf,64); printf("%d\n",result); return 0; }
程式結果是零,說明程式有錯。利用單步除錯發現sum函式寫錯了
監視視窗可以單獨只檢視某個變數的情況。記憶體視窗輸入p可以看到指標p對應的記憶體,觀看變數a的記憶體時輸入&a。a=0x12345678對應的記憶體為78 56 34 12共四個位元組。
程式崩潰的原因分類
-
一個變數未初化、未賦值,就讀取它的值。( 這屬於邏輯問題,往往是粗心大意的導致的 )
-
函式棧溢位(1)定義了一個體積太大的區域性變數(2)函式巢狀呼叫,層次過深(如無窮遞迴)
int buf[1024*1024*16]; //這個變數體積太大,應該用malloc或new來動態分配記憶體
//無窮的遞迴呼叫 #include <stdio.h> #include <stdlib.h> void a(); void b(); void a() { printf("Calling a() ...\n"); b(); } void b() { printf("Calling b() ...\n"); a(); } int main() { a(); return 0; }
-
陣列越界訪問
-
指標的目標物件不可用,為空指標,野指標(指標未賦值,已經free/delete了卻還要用,不恰當的指標強制轉換要求)
//野指標:不恰當的強制轉換 #include <stdio.h> int main() { int a = 10; double* p = (double*) &a; *p = 123.345; // 程式崩潰 return 0; }