診斷服務

MFC 程式庫提供許多診斷服務,可讓您更輕鬆地對程式進行偵錯。 這些診斷服務包含巨集和全域函式,可讓您追蹤程式的記憶體配置、在執行階段傾印物件的內容,以及在執行階段列印偵錯訊息。 診斷服務的巨集和全域函式可分為下列分類:

  • 一般診斷巨集

  • 一般診斷函式和變數

  • 物件診斷函式

這些巨集和函式都可以在 MFC 的偵錯和發行版本中,供所有衍生自 CObject 的類別使用。 不過,除了DEBUG_NEW和 VERIFY 以外的所有專案,都不會在發行版本本中執行任何動作。

在偵錯程式庫中,所有配置的記憶體區塊都會以一系列的「防護位元組」括住。如果這些位元組受到錯誤記憶體寫入的干擾,則診斷常式可能會回報問題。 如果您在實作檔中包含此行:

#define new DEBUG_NEW

在您的實作檔案中,所有對 的呼叫 new 都會儲存記憶體配置發生所在的檔案名和行號。 CMemoryState::DumpAllObjectsSince 函式會顯示這項額外的資訊,讓您找出記憶體流失的問題。 如需診斷輸出的其他資訊,另請參閱 CDumpContext 類別。

此外,C 執行階段程式庫也支援一組可用來偵錯應用程式的診斷函式。 如需詳細資訊,請參閱<執行階段程式庫參考>中的 偵錯常式

MFC 一般診斷巨集

名稱 描述
ASSERT 如果指定的運算式在程式庫的偵錯版本中評估為 FALSE ,則會列印訊息,再中止程式。
ASSERT_KINDOF 測試物件是指定類別的物件,還是衍生自指定類別之類別的物件。
ASSERT_VALID 藉由呼叫物件的 AssertValid 成員函式來測試其內部有效性,通常會覆寫自 CObject
DEBUG_NEW 提供偵錯模式中所有物件配置的檔案名稱和行號,以協助找出記憶體流失的問題。
DEBUG_ONLY 類似於 ASSERT ,但不會測試運算式的值;適用於只能在偵錯模式中執行的程式碼。
ENSURE 和 ENSURE_VALID 使用 來驗證資料正確性。
THIS_FILE 展開至正在編譯的檔案名。
TRACE 提供此程式庫之偵錯版本中類似 printf的功能。
VERIFY 類似於 ASSERT ,但不僅會評估此程式庫之發行版本中的運算式,也會評估偵錯版本中的運算式。

MFC 一般診斷變數和函式

名稱 描述
afxDump 全域變數,可將 CDumpContext 資訊傳送至偵錯工具輸出視窗或偵錯終端機。
afxMemDF 全域變數,可控制偵錯記憶體配置器的行為。
AfxCheckError 全域變數,可用來測試所傳遞的 SCODE 以查看其是否為錯誤;如果是,則擲回適當的錯誤。
AfxCheckMemory 檢查目前配置之所有記憶體的完整性。
AfxDebugBreak 導致執行中斷。
AfxDump 如果在偵錯工具中呼叫,則會一面進行偵錯,一面傾印物件的狀態。
AfxDump 在偵錯時傾印物件狀態的內部函式。
AfxDumpStack 產生目前堆疊的映像。 這個函式一律會以靜態方式連結。
AfxEnableMemoryLeakDump 啟用記憶體流失傾印。
AfxEnableMemoryTracking 開啟和關閉記憶體追蹤。
AfxIsMemoryBlock 確認已適當地配置記憶體區塊。
AfxIsValidAddress 確認記憶體位址範圍落在程式的範圍內。
AfxIsValidString 判斷字串指標是否有效。
AfxSetAllocHook 允許對每個記憶體配置呼叫函式。

MFC 物件診斷函式

名稱 描述
AfxDoForAllClasses 針對所有可支援執行階段類型檢查的 CObject衍生類別執行指定的函式。
AfxDoForAllObjects 在使用 new 配置的所有 CObject 衍生物件上執行指定的函式。

MFC 編譯宏

名稱 描述
_AFX_SECURE_NO_WARNINGS 隱藏關於使用被取代 MFC 的功能的編譯器警告。

_AFX_SECURE_NO_WARNINGS

隱藏關於使用被取代 MFC 的功能的編譯器警告。

語法

_AFX_SECURE_NO_WARNINGS

範例

如果未定義,此程式碼範例會造成編譯器警告 _AFX_SECURE_NO_WARNINGS

// define this before including any afx files in *pch.h* (*stdafx.h* in Visual Studio 2017 and earlier)
#define _AFX_SECURE_NO_WARNINGS

// . . .

CRichEditCtrl* pRichEdit = new CRichEditCtrl;
pRichEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,
   CRect(10,10,100,200), pParentWnd, 1);
char sz[256];
pRichEdit->GetSelText(sz);

AfxDebugBreak

呼叫此函式,以在執行 MFC 應用程式的偵錯版本時造成中斷(在 呼叫 AfxDebugBreak 的位置)。

語法

void AfxDebugBreak( );

備註

AfxDebugBreak 在 MFC 應用程式的發行版本本中沒有作用,因此應該移除。 此函式只應用於 MFC 應用程式中。 使用 WIN32 API 版本 DebugBreak ,在非 MFC 應用程式中造成中斷。

需求

標頭: afxver_.h

ASSERT

評估其引數。

ASSERT(booleanExpression)

參數

booleanExpression
指定評估為非零或 0 的運算式(包括指標值)。

備註

如果結果為 0,宏會列印診斷訊息並中止程式。 如果條件為非零,則不會執行任何動作。

診斷資訊的格式如下

assertion failed in file <name> in line <num>

其中 name 是來源檔案的名稱,而 num 是來源檔案中失敗之判斷提示的行號。

在 MFC 的 Release 版本中,ASSERT 不會評估運算式,因此不會中斷程式。 如果不論環境為何,都必須評估運算式,請使用 VERIFY 宏取代 ASSERT。

注意

此函式僅適用于 MFC 的偵錯版本。

範例

CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(pcage != NULL);
ASSERT(pcage->IsKindOf(RUNTIME_CLASS(CAge)));
// Terminates program only if pcage is NOT a CAge*.   

需求

標頭: afx.h

ASSERT_KINDOF

這個宏判斷提示指向的物件是指定類別的物件,或是衍生自指定類別之類別的物件。

ASSERT_KINDOF(classname, pobject)

參數

classname
衍生類別 CObject 的名稱。

pobject
類別物件的指標。

備註

pobject 參數應該是 物件的指標,而且可以是 const 。 指向 的物件和 類別必須支援 CObject 執行時間類別資訊。 例如,若要確保 pDocument 是 類別物件的 CMyDoc 指標,或其任何衍生專案,您可以撰寫下列程式碼:

ASSERT_KINDOF(CMyDoc, pDocument);

ASSERT_KINDOF使用宏與撰寫程式碼完全相同:

ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));

此函式僅適用于以 [DECLARE_DYNAMIC] 宣告的類別(run-time-object-model-services.md#declare_dynamic 或 DECLARE_SERIAL 宏。

注意

此函式僅適用于 MFC 的偵錯版本。

需求

標頭: afx.h

ASSERT_VALID

使用 來測試有關物件內部狀態有效性的假設。

ASSERT_VALID(pObject)

參數

pObject
指定衍生自 CObject 且具有覆寫成員函式版本的 AssertValid 類別物件。

備註

ASSERT_VALID呼叫 AssertValid 做為其引數傳遞之物件的成員函式。

在 MFC 的發行版本本中,ASSERT_VALID不會執行任何動作。 在偵錯版本中,它會驗證指標、檢查 Null,以及呼叫物件自己的 AssertValid 成員函式。 如果其中任何一項測試失敗,警示訊息會以與 ASSERT 相同的方式顯示。

注意

此函式僅適用于 MFC 的偵錯版本。

如需詳細資訊和範例,請參閱 偵錯 MFC 應用程式

範例

// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);

需求

標頭: afx.h

DEBUG_NEW

協助尋找記憶體流失。

#define  new DEBUG_NEW

備註

您可以在程式中的任何地方使用DEBUG_NEW,您通常會使用 new 運算子來配置堆積儲存體。

在偵錯模式中(定義_DEBUG 符號時 ),DEBUG_NEW會追蹤其配置之每個物件的檔案名和行號。 然後,當您使用 CMemoryState::D umpAllObjectsSince 成員函式時,配置DEBUG_NEW的每個物件都會以配置所在的檔案名和行號來顯示。

若要使用DEBUG_NEW,請將下列指示詞插入原始程式檔中:

#define new DEBUG_NEW

插入此指示詞之後,預處理器會在您使用 new 的位置插入DEBUG_NEW,而 MFC 會執行其餘作業。 當您編譯器的發行版本本時,DEBUG_NEW解析為簡單的 new 作業,而且不會產生檔案名和行號資訊。

注意

在舊版的 MFC (4.1 和更早版本中),您需要將所有稱為IMPLEMENT_DYNCREATE或IMPLEMENT_SERIAL宏的語句放在 #define 後面。 但目前已經不是必要的了。

需求

標頭: afx.h

DEBUG_ONLY

在偵錯模式中(定義_DEBUG 符號時 ),DEBUG_ONLY評估其引數。

DEBUG_ONLY(expression)

備註

在發行組建中,DEBUG_ONLY不會評估其引數。 當您的程式碼應該只在偵錯組建中執行時,這會很有用。

DEBUG_ONLY宏相當於 搭配 和 #ifdef _DEBUG#endif 的周圍 運算式

範例

void ExampleFunc(char* p, int size, char fill)
{
   char* q;               // working copy of pointer 
   VERIFY(q = p);         // copy buffer pointer and validate
   ASSERT(size >= 100);   // make sure buffer is at least 100 bytes
   ASSERT(isalpha(fill)); // make sure fill character is alphabetic
   // if fill character is invalid, substitute 'X' so we can continue
   // debugging after the preceding ASSERT fails.
   DEBUG_ONLY(fill = (isalpha(fill)) ? fill : 'X');
}

需求

標頭: afx.h

ENSURE 和 ENSURE_VALID

使用 來驗證資料正確性。

語法

ENSURE(  booleanExpression )
ENSURE_VALID( booleanExpression  )

參數

booleanExpression
指定要測試的布林運算式。

備註

這些宏的目的是要改善參數的驗證。 宏可防止在程式碼中進一步處理不正確的參數。 不同于 ASSERT 宏,ENSURE 宏除了產生判斷提示之外,也會擲回例外狀況。

宏的行為有兩種方式,根據專案組態。 宏會呼叫 ASSERT,然後在判斷提示失敗時擲回例外狀況。 因此,在偵錯組態中(也就是定義_DEBUG的位置)宏會在發行組態中產生判斷提示和例外狀況,宏只會產生例外狀況(ASSERT 不會評估 Release 組態中的運算式)。

宏ENSURE_ARG的作用就像 ENSURE 宏一樣。

ENSURE_VALID會呼叫ASSERT_VALID宏(只有在偵錯組建中才會有效果)。 此外,如果指標為 Null,ENSURE_VALID會擲回例外狀況。 Null 測試會在偵錯和發行組態中執行。

如果其中任何一項測試失敗,警示訊息會以與 ASSERT 相同的方式顯示。 如有需要,宏會擲回不正確引數例外狀況。

需求

標頭: afx.h

THIS_FILE

展開至正在編譯的檔案名。

語法

THIS_FILE

備註

資訊是由 ASSERT 和 VERIFY 宏使用。 應用程式精靈和程式碼精靈會將宏放在他們建立的原始程式碼檔案中。

範例

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// __FILE__ is one of the six predefined ANSI C macros that the
// compiler recognizes.

需求

標頭: afx.h

TRACE

將指定的字串傳送至目前應用程式的偵錯工具。

TRACE(exp)
TRACE(DWORD  category,  UINT  level, LPCSTR lpszFormat, ...)

備註

如需 TRACE 的描述, 請參閱 ATLTRACE2。 TRACE 和 ATLTRACE2具有相同的行為。

在 MFC 的偵錯版本中,這個宏會將指定的字串傳送至目前應用程式的偵錯工具。 在發行組建中,此宏不會編譯成任何專案(完全不會產生任何程式碼)。

如需詳細資訊,請參閱 偵錯 MFC 應用程式

需求

標頭: afx.h

VERIFY

在 MFC 的偵錯版本中,評估其引數。

VERIFY(booleanExpression)

參數

booleanExpression
指定評估為非零或 0 的運算式(包括指標值)。

備註

如果結果為 0,宏會列印診斷訊息並停止程式。 如果條件為非零,則不會執行任何動作。

診斷資訊的格式如下

assertion failed in file <name> in line <num>

其中 name 是來源檔案的名稱, 而 num 是來源檔案中失敗之判斷提示的行號。

在 MFC 的發行版本本中,VERIFY 會評估運算式,但不會列印或中斷程式。 例如,如果運算式是函式呼叫,則會進行呼叫。

範例

// VERIFY can be used for things that should never fail, though
// you may want to make sure you can provide better error recovery
// if the error can actually cause a crash in a production system.

// It _is_ possible that GetDC() may fail, but the out-of-memory
// condition that causes it isn't likely. For a test application,
// this use of VERIFY() is fine. For any production code, this
// usage is dubious.

// get the display device context
HDC hdc;
VERIFY((hdc = ::GetDC(hwnd)) != NULL);

// give the display context back
::ReleaseDC(hwnd, hdc);

需求

標頭: afx.h

afxDump (MFC 中的 CDumpCoNtext)

在您的應用程式中提供基本的物件傾印功能。

CDumpContext  afxDump;

備註

afxDump 是預先定義的 CDumpCoNtext 物件,可讓您將資訊傳送 CDumpContext 至偵錯工具輸出視窗或偵錯終端機。 一般而言,您會將 做為 的參數 CObject::Dump 提供給 afxDump

在 Windows NT 和所有版本的 Windows 下,當您偵錯應用程式時, afxDump 輸出會傳送至 Visual C++ 的 [輸出偵錯] 視窗。

此變數只會在 MFC 的偵錯版本中定義。 如需 的詳細資訊 afxDump ,請參閱 偵錯 MFC 應用程式

範例

// example for afxDump
CPerson* pMyPerson = new CPerson;
// set some fields of the CPerson object...
//..
// now dump the contents
#ifdef _DEBUG
afxDump << _T("Dumping myPerson:\n");
pMyPerson->Dump(afxDump);
afxDump << _T("\n");
#endif

需求

標頭: afx.h

AfxDump (內部)

MFC 在偵錯時用來傾印物件狀態的內部函式。

語法

void AfxDump(const CObject* pOb);

參數

Pob
衍生自 CObject 之類別物件的指標。

備註

AfxDump 會呼叫物件的 Dump 成員函式,並將資訊傳送至變數所 afxDump 指定的位置。 AfxDump 僅適用于 MFC 的偵錯版本。

您的程式碼不應該呼叫 AfxDump ,但應該改為呼叫 Dump 適當物件的成員函式。

需求

標頭: afx.h

afxMemDF

此變數可從偵錯工具或程式存取,並可讓您微調配置診斷。

int  afxMemDF;

備註

afxMemDF 可以具有列舉所 afxMemDF 指定的下列值:

  • allocMemDF 開啟偵錯配置器 (偵錯程式庫中的預設設定)。

  • delayFreeMemDF 延遲釋放記憶體。 當程式釋放記憶體區塊時,配置器不會將該記憶體傳回基礎作業系統。 這會將記憶體壓力上限放在您的程式上。

  • checkAlwaysMemDF 每次配置或釋放記憶體時呼叫 AfxCheckMemory 。 這會大幅降低記憶體配置和解除配置的速度。

範例

afxMemDF = allocMemDF | checkAlwaysMemDF;

需求

標頭: afx.h

AfxCheckError

此函式會測試通過的 SCODE,以查看其是否為錯誤。

void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*

備註

如果是錯誤,函式會擲回例外狀況。 如果傳遞的 SCODE 是E_OUTOFMEMORY,函式會呼叫 AfxThrowMemoryException 來擲回 CMemoryException 。 否則,函式會呼叫 AfxThrowOleException 來擲回 COleException 。

這個函式可用來檢查對應用程式中 OLE 函式呼叫的傳回值。 藉由在應用程式中以此函式測試傳回值,您可以用最少的程式碼因應錯誤狀況。

注意

這個函式在偵錯和非偵錯組建中具有相同的效果。

範例

AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
   IID_IDispatch, (LPVOID*)& pWMPDispatch));

oddWMP.AttachDispatch(pWMPDispatch, TRUE);

需求

標頭: afx.h

AfxCheckMemory

此函式會驗證可用的記憶體集區,並視需要列印錯誤訊息。

BOOL  AfxCheckMemory();

傳回值

如果沒有記憶體錯誤,則為非零;否則為 0。

備註

如果函式未偵測到記憶體損毀,則不會列印任何內容。

會檢查堆積上目前配置的所有記憶體區塊,包括 由 new 配置但不是由直接呼叫基礎記憶體配置器所配置的記憶體區塊,例如 malloc 函式或 GlobalAlloc Windows 函式。 如果發現有任何區塊損毀,則會將訊息列印至偵錯工具輸出。

如果您包含這一行

#define new DEBUG_NEW

在程式模組中,接著會呼叫 ,以顯示 AfxCheckMemory 配置記憶體的檔案名和行號。

注意

如果您的模組包含一或多個可序列化類別的實作,則必須將這一行放在 #define 最後一個IMPLEMENT_SERIAL宏呼叫之後。

此函式僅適用于 MFC 的偵錯版本。

範例

CAge* pcage = new CAge(21);  // CAge is derived from CObject.
Age* page = new Age(22);     // Age is NOT derived from CObject.
*(((char*)pcage) - 1) = 99;   // Corrupt preceding guard byte
*(((char*)page) - 1) = 99;    // Corrupt preceding guard byte
AfxCheckMemory();

需求

標頭: afx.h

AfxDump (MFC)

在偵錯工具中呼叫此函式,以在偵錯時傾印物件的狀態。

void AfxDump(const CObject* pOb);

參數

Pob
衍生自 CObject 之類別物件的指標。

備註

AfxDump 會呼叫物件的 Dump 成員函式,並將資訊傳送至變數所 afxDump 指定的位置。 AfxDump 僅適用于 MFC 的偵錯版本。

您的程式碼不應該呼叫 AfxDump ,但應該改為呼叫 Dump 適當物件的成員函式。

需求

標頭: afx.h

AfxDumpStack

這個全域函式可用來產生目前堆疊的影像。

void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);

參數

dwTarget
表示傾印輸出的目標。 可以使用位 OR ( | ) 運算子結合的可能值如下所示:

  • AFX_STACK_DUMP_TARGET_TRACE透過 TRACE 宏傳送輸出。 TRACE 宏只會在偵錯組建中產生輸出;它不會在發行組建中產生任何輸出。 此外,除了偵錯工具之外,TRACE 也可以重新導向至其他目標。

  • AFX_STACK_DUMP_TARGET_DEFAULT將傾印輸出傳送至預設目標。 針對偵錯組建,輸出會移至 TRACE 宏。 在發行組建中,輸出會移至剪貼簿。

  • AFX_STACK_DUMP_TARGET_CLIPBOARD僅將輸出傳送至剪貼簿。 資料會使用剪貼簿格式的CF_TEXT純文字放在剪貼簿上。

  • AFX_STACK_DUMP_TARGET_BOTH同時將輸出傳送至剪貼簿和 TRACE 宏。

  • AFX_STACK_DUMP_TARGET_ODS 透過 Win32 函式 OutputDebugString() 直接將輸出傳送至偵錯工具。 當偵錯工具附加至進程時,此選項會在偵錯和發行組建中產生偵錯工具輸出。 AFX_STACK_DUMP_TARGET_ODS一律會到達偵錯工具(如果已附加),而且無法重新導向。

備註

下列範例會反映從 MFC 對話方塊應用程式中的按鈕處理常式呼叫 AfxDumpStack 所產生的輸出單行:

=== begin AfxDumpStack output ===
00427D55: DUMP2\DEBUG\DUMP2.EXE! void AfxDumpStack(unsigned long) + 181 bytes
0040160B: DUMP2\DEBUG\DUMP2.EXE! void CDump2Dlg::OnClipboard(void) + 14 bytes
0044F884: DUMP2\DEBUG\DUMP2.EXE! int _AfxDispatchCmdMsg(class CCmdTarget *,
unsigned int,int,void ( CCmdTarget::*)(void),void *,unsigned int,struct
AFX_CMDHANDLE
0044FF7B: DUMP2\DEBUG\DUMP2.EXE! virtual int CCmdTarget::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 626 bytes
00450C71: DUMP2\DEBUG\DUMP2.EXE! virtual int CDialog::OnCmdMsg(unsigned
int,int,void *,struct AFX_CMDHANDLERINFO *) + 36 bytes
00455B27: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnCommand(unsigned
int,long) + 312 bytes
00454D3D: DUMP2\DEBUG\DUMP2.EXE! virtual int CWnd::OnWndMsg(unsigned
int,unsigned int,long,long *) + 83 bytes
00454CC0: DUMP2\DEBUG\DUMP2.EXE! virtual long CWnd::WindowProc(unsigned
int,unsigned int,long) + 46 bytes
004528D9: DUMP2\DEBUG\DUMP2.EXE! long AfxCallWndProc(class CWnd *,struct
HWND__ *,unsigned int,unsigned int,long) + 237 bytes
00452D34: DUMP2\DEBUG\DUMP2.EXE! long AfxWndProc(struct HWND__ *,unsigned
int,unsigned int,long) + 129 bytes
BFF73663: WINDOWS\SYSTEM\KERNEL32.DLL! ThunkConnect32 + 2148 bytes
BFF928E0: WINDOWS\SYSTEM\KERNEL32.DLL! UTUnRegister + 2492 bytes
=== end AfxDumpStack() output ===

上述輸出中的每個行都會指出最後一個函式呼叫的位址、包含函式呼叫之模組的完整路徑名稱,以及呼叫的函式原型。 如果堆疊上的函式呼叫未在函式的確切位址發生,則會顯示位元組位移。

例如,下表描述上述輸出的第一行:

輸出 描述
00427D55: 最後一個函式呼叫的傳回位址。
DUMP2\DEBUG\DUMP2.EXE! 包含函式呼叫之模組的完整路徑名稱。
void AfxDumpStack(unsigned long) 呼叫的函式原型。
+ 181 bytes 從函式原型位址(在此案例中為 void AfxDumpStack(unsigned long) )到傳回位址的位元組位移(在此案例中為 00427D55 )。

AfxDumpStack 適用于 MFC 程式庫的偵錯和非偵錯版本;不過,即使可執行檔在共用 DLL 中使用 MFC,函式一律會以靜態方式連結。 在共用程式庫實作中,函式可在 MFCS42 中找到。LIB 程式庫(及其變體)。

若要成功使用此函式:

  • IMAGEHLP.DLL 檔案必須位於您的路徑上。 如果您沒有此 DLL,函式會顯示錯誤訊息。 如需 IMAGEHLP 所提供的函式集資訊,請參閱 影像說明程式庫

  • 堆疊上具有框架的模組必須包含偵錯資訊。 如果沒有包含偵錯資訊,函式仍會產生堆疊追蹤,但追蹤會較不詳細。

需求

標頭: afx.h

AfxEnableMemoryLeakDump

啟用和停用AFX_DEBUG_STATE解構函式中的記憶體流失傾印。

BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);

參數

bDump
[in]TRUE 表示已啟用記憶體流失轉儲;FALSE 表示記憶體流失傾印已停用。

傳回值

此旗標先前的值。

備註

當應用程式卸載 MFC 程式庫時,MFC 程式庫會檢查記憶體流失。 此時,任何記憶體流失會透過 Visual Studio 的 [偵錯] 視窗回報給使用者。

如果您的應用程式在 MFC 程式庫之前先載入另一個程式庫,系統會將該程式庫中的一些記憶體配置誤報為記憶體流失。 因為 MFC 程式庫發生記憶體流失誤報的情況,這些誤報可能會導致您的應用程式關閉速度很慢。 在這種情況下,請使用 AfxEnableMemoryLeakDump 以停用記憶體流失傾印。

注意

如果您使用這個方法來關閉記憶體流失傾印,就不會收到應用程式中有效的記憶體流失報告。 因此,僅有當您確信記憶體流失報告包含誤報的記憶體流失,才建議使用這個方法。

需求

標頭: afx.h

AfxEnableMemoryTracking

診斷記憶體追蹤通常會在 MFC 的偵錯版本中啟用。

BOOL AfxEnableMemoryTracking(BOOL bTrack);

參數

bTrack
將此值設定為 TRUE 會開啟記憶體追蹤;FALSE 將其關閉。

傳回值

追蹤啟用旗標的上一個設定。

備註

使用此函式來停用您知道正確配置區塊的程式碼區段追蹤。

如需 的詳細資訊 AfxEnableMemoryTracking ,請參閱 偵錯 MFC 應用程式

注意

此函式僅適用于 MFC 的偵錯版本。

範例

BOOL CMyWinApp::InitInstance()
{
#ifdef _DEBUG
   // Disable tracking of memory for the scope of the InitInstance()
   AfxEnableMemoryTracking(FALSE);
#endif  // _DEBUG

   // ...

#ifdef _DEBUG
   // Re-enable tracking of memory
   AfxEnableMemoryTracking(TRUE);
#endif  // _DEBUG

   return TRUE;
}

需求

標頭: afx.h

AfxIsMemoryBlock

測試記憶體位址,以確定它代表診斷版本 new 所配置的目前使用中記憶體區塊。

BOOL AfxIsMemoryBlock(
    const void* p,
    UINT nBytes,
    LONG* plRequestNumber = NULL);

參數

p
指向要測試的記憶體區塊。

nBytes
包含以位元組為單位的記憶體區塊長度。

plRequestNumber
long指向將填入記憶體區塊配置序號的整數,如果它不代表目前作用中的記憶體區塊,則為零。

傳回值

如果記憶體區塊目前已配置且長度正確,則為非零;否則為 0。

備註

它也會根據原始配置的大小檢查指定的大小。 如果函式傳回非零,則會在 plRequestNumber 傳回配置序號。 這個數位代表區塊相對於所有其他 new 配置配置的順序。

範例

CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));

需求

標頭: afx.h

AfxIsValidAddress

測試任何記憶體位址,以確保它完全包含在程式的記憶體空間內。

BOOL AfxIsValidAddress(
    const void* lp,
    UINT nBytes,
    BOOL bReadWrite = TRUE);

參數

Lp
指向要測試的記憶體位址。

nBytes
包含要測試的記憶體位元組數目。

bReadWrite
指定記憶體是用於讀取和寫入 (TRUE) 還是唯讀取 (FALSE)。

傳回值

在偵錯組建中,如果指定的記憶體區塊完全包含在程式的記憶體空間內,則為非零;否則為 0。

在非偵錯組建中,如果 lp 不是 Null,則為非零,否則為 0。

備註

位址不限於 所 new 配置的區塊。

範例

// Allocate a 5 character array, which should have a valid memory address.
char* arr = new char[5];

// Create a null pointer, which should be an invalid memory address.
char* null = (char*)0x0;

ASSERT(AfxIsValidAddress(arr, 5));
ASSERT(!AfxIsValidAddress(null, 5));

需求

標頭: afx.h

AfxIsValidString

使用此函式來判斷字串的指標是否有效。

BOOL  AfxIsValidString(
    LPCSTR lpsz,
    int nLength = -1);

參數

lpsz
要測試的指標。

nLength
指定要測試的字串長度,以位元組為單位。 值 -1 表示字串會以 Null 結束。

傳回值

在偵錯組建中,如果指定的指標指向指定大小的字串,則為非零;否則為 0。

在非偵錯組建中,如果 lpsz 不是 Null,則為非零,否則為 0。

範例

// Create a character string which should be valid.
char str[12] = "hello world";

// Create a null pointer, which should be an invalid string.
char* null = (char*)0x0;

ASSERT(AfxIsValidString(str, 12));
ASSERT(!AfxIsValidString(null, 5));

需求

標頭: afx.h

AfxSetAllocHook

設定勾點,可在配置每個記憶體區塊之前呼叫指定的函式。

AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);

參數

pfnAllocHook
指定要呼叫的函式名稱。 如需配置函式的原型,請參閱。

傳回值

如果您想要允許配置,則為非零;否則為 0。

備註

Microsoft Foundation Class Library debug-memory 配置器可以呼叫使用者定義的攔截函式,允許使用者監視記憶體配置,並控制是否允許配置。 配置攔截函式的原型如下:

BOOL AFXAPI AllocHook(size_t,BOOL,LONG bObjectnSizelRequestNumber ):

nSize
建議記憶體配置的大小。

bObject
如果配置是針對衍生的物件,則為 TRUE,否則為 CObject FALSE。

lRequestNumber
記憶體配置的序號。

請注意,AFXAPI 呼叫慣例表示被呼叫者必須從堆疊中移除參數。

需求

標頭: afx.h

AfxDoForAllClasses

針對應用程式記憶體空間中的所有可 CObject 序列化衍生類別,呼叫指定的反復專案函式。

void
AFXAPI AfxDoForAllClasses(
    void (* pfn)(const CRuntimeClass* pClass, void* pContext),
    void* pContext);

參數

pfn
指向要針對每個類別呼叫的反復專案函式。 函式引數是 物件的指標 CRuntimeClass ,以及呼叫端提供給函式的額外資料的 void 指標。

pContext
指向呼叫端可以提供給反復專案函式的選擇性資料。 此指標可以是 Null。

備註

CObject 序列化衍生類別是使用 DECLARE_SERIAL 宏衍生的類別。 在 pCoNtext 傳遞至 AfxDoForAllClasses 的指標會在每次呼叫時傳遞至指定的反復專案函式。

注意

此函式僅適用于 MFC 的偵錯版本。

範例

#ifdef _DEBUG
void DoForAllClasses(const CRuntimeClass* pClass, void* pContext)
{
   ASSERT(pContext != NULL);
   CString* pStr = (CString*)pContext;

   *pStr += pClass->m_lpszClassName;
   *pStr += _T("\n");
}
#endif

 

#ifdef _DEBUG
CString cStr;
AfxDoForAllClasses(DoForAllClasses, &cStr);
AfxMessageBox(cStr);
#endif

需求

標頭: afx.h

AfxDoForAllObjects

針對已使用 new 配置的所有衍生自 CObject 的物件執行指定的反復專案函式。

void AfxDoForAllObjects(
    void (* pfn)(CObject* pObject, void* pContext),
    void* pContext);

參數

pfn
指向要針對每個物件執行的反復專案函式。 函式引數是 的 CObject 指標,而 void 指標指向呼叫端提供給函式的額外資料。

pContext
指向呼叫端可以提供給反復專案函式的選擇性資料。 此指標可以是 Null。

備註

不會列舉堆疊、全域或内嵌物件。 在 pCoNtext 傳遞至 AfxDoForAllObjects 的指標會在每次呼叫時傳遞至指定的反復專案函式。

注意

此函式僅適用于 MFC 的偵錯版本。

範例

#ifdef _DEBUG
void DoForAllObjects(CObject* pObject, void* pContext)
{
   int* pnCount = (int*)pContext;

   pObject->AssertValid();
   if (pnCount != NULL)
      (*pnCount)++;
}
#endif // _DEBUG

 

#ifdef _DEBUG
//AfxDoForAllObjects will call the function DoForAllObjects 
//For each CObject-derived object that is allocated on the heap
int nCount = 0;
AfxDoForAllObjects(DoForAllObjects, &nCount);
TRACE("%d Objects Checked\n", nCount);
#endif

另請參閱

宏和全域
CObject::D ump