MFC中高階除錯技術

2021-04-13 02:03:56 字數 2893 閱讀 1229

mfc中高階除錯技術

1. trace巨集的利用

trace巨集有點像我們以前在c語言中用的printf函式,使程式在執行過程中輸出一些除錯資訊,使我們能了解程式的一些狀態。但有一點不同的是,trace巨集只有在除錯狀態下才有輸出,而以前用的printh函式在任何情況下都有輸出。同printf函式一樣,trace巨集可以接受多個引數,如:

int x = 1;

int y = 16;

float z = 32.0;

trace( "this is a trace statement/n" );

trace( "the value of x is %d/n", x );

trace( "x = %d and y = %d/n", x, y );

trace( "x = %d and y = %d and z = %f ", x, y, z );

要注意的是trace巨集只對debug版本的工程產生作用,在release版本的工程中,trace巨集將被忽略。

2. assert巨集的利用

在開發過程中我們可以假設只要程式執行正確,某一條件肯定成立。若不成立,那麼我們可以斷言程式肯定出錯。在這種情況下我們可要利用assert來設定斷言。assert巨集的引數是乙個邏輯表示式,在程式執行過程中,若該邏輯表示式為真,則不會發生任何動作;若此表示式為假,則系統彈出乙個對話方塊警告你,並停止程式的執行。同時要求你作出選擇:取消、忽略和重試。若你選擇取消,則系統將停止程式的執行;若你選擇忽略,則系統將忽略該錯誤,並繼續執行程式;若你選擇重試,則系統將重新計算該表示式,並啟用偵錯程式。同trace巨集一樣,assert巨集只對debug版本的工程產生作用,在release版本的工程中,trace巨集將被忽略。

下面的示例顯示如何使用assert檢查函式的返回值:

int x = somefunc(y);

assert( x >=  0);   // 如果x為負,則斷言失敗。

可將斷言用於:

(1)可以使用斷言語句捕捉邏輯錯誤。可以在程式邏輯必須為真的條件上設定斷言。除非發生邏輯錯誤,否則斷言對程式無任何影響。

(2)可以使用斷言語句檢查操作的結果。斷言對於快速直觀地檢查不明顯的操作結果最有價值。

(3)可以使用斷言在**中已處理了錯誤的點處測試錯誤型別。

3. assert_valid巨集的使用

assert_valid巨集用來在程式執行時檢查乙個物件的內部合法性。比如說,現在有乙個學生物件,我們知道每乙個學生的年齡乙個大於零,若年齡小於零,則該學生物件肯定有問題。事實上,assert_valid巨集就是轉化為物件的成員函式assertvalid的呼叫,只是這中方法更安全。它的引數是乙個物件指標,通過這個指標來呼叫它的assertvalid成員函式。

與此相配套,每當建立從cobject類繼承而來的乙個新類時,可以過載該成員函式,以執行特定的合法性檢查。下面的示例顯示如何宣告assertvalid函式:

sclass cperson : public cobject ;

當重寫assertvalid時,在執行程式的檢查之前請呼叫assertvalid的基類模板。然後使用assert巨集來檢查派生類特有的成員,如下所示:

#ifdef _debug

void cperson::assertvalid( ) const

#endif

4. 記憶體漏洞的檢查

在c++和c語言中指標問題也就是記憶體申請與釋放是乙個令人頭疼的事情,假如申請了記憶體,但沒有釋放,並且程式需要長時間的執行,那麼,系統資源將逐漸減少。當系統的資源全部用完時,系統將崩潰。所以在開發過程中一定要保證資源的完全釋放。

檢查記憶體漏洞的方法如下:

假如要檢查某一程式段是否有記憶體漏洞,只需在這一程式段的開始要求系統做一次記憶體使用情況的對映,記錄下程式開始時的記憶體使用情況,然後在程式段的末尾再使系統做一次記憶體對映。比較兩次對映,以檢查是否有未釋放的記憶體,加入有未釋放的記憶體,根據這一塊中有關分配情況的資訊來告訴使用者在那裡申請的記憶體未釋放。

具體的講,檢查記憶體漏洞需要一下幾步:

(1)在所檢測的程式段開始處建立乙個cmemorystate物件,呼叫其成員函式checkpoint,以取得當前記憶體使用情況的對映;

(2)在所檢測的程式段的末尾處再建立乙個cmemorystate物件,呼叫其成員函式checkpoint,以取得當前記憶體使用情況的對映;

(3)再建立第3個cmemorystate物件,呼叫其成員函式difference,把第乙個cmemorystate物件和第二個cmemorystate物件作為其引數,如果兩次記憶體對映不相同,則該函式返回非零,說明此程式段中有記憶體漏洞。

下面來看乙個例子:

#ifdef _debug

cmemorystate oldmemstate, newmemstate,  diffmemstate;

oldmemstate.checkpoint();

#endif

cstring s = "this is a frame variable";

// the next object is a heap object

cperson* p = new cperson("**ith", "alan", "581_0215");

#ifdef _debug

newmemstate.checkpoint();

if ( diffmemstate.difference(oldmemstate, newmemstate ) )

在此例中,首先定義了3個cmemorystate物件。然後在需要檢測記憶體漏洞的**前後分別呼叫cmemorystate物件成員函式checkpoint,再後呼叫第3個cmemorystate物件的成員函式difference來判斷是否有記憶體漏洞,如果有,則使用trace巨集列印提示訊息。

MFC中高階除錯技術

mfc中高階除錯技術 1.trace巨集的利用 trace巨集有點像我們以前在c語言中用的printf函式,使程式在執行過程中輸出一些除錯資訊,使我們能了解程式的一些狀態。但有一點不同的是,trace巨集只有在除錯狀態下才 有輸出,而以前用的printh函式在任何情況下都有輸出。同printf函式一...

MFC中高階除錯技術

mfc中高階除錯技術 1.trace巨集的利用 trace巨集有點像我們以前在c語言中用的printf函式,使程式在執行過程中輸出一些除錯資訊,使我們能了解程式的一些狀態。但有一點不同的是,trace巨集只有在除錯狀態下才 有輸出,而以前用的printh函式在任何情況下都有輸出。同printf函式一...

shared ptr中高階應用

在編寫基於虛函式的多型 時,指標的型別轉換很有用,比如把乙個基類的指標轉換成乙個派生類的指標或者反過來。但是對於shared ptr不能使用諸如static cast p.get 的形式,這樣會導致轉型後的指標無法再被shared ptr正確管理。為了支援類似的用法,shared ptr提供了類似的...