Diagnostické služby
Knihovna tříd Microsoft Foundation poskytuje mnoho diagnostických služeb, které usnadňují ladění programů. Mezi tyto diagnostické služby patří makra a globální funkce, které umožňují sledovat přidělení paměti programu, vypsat obsah objektů během běhu a tisknout zprávy ladění během běhu. Makra a globální funkce pro diagnostické služby jsou seskupené do následujících kategorií:
Obecná diagnostická makra
Obecné diagnostické funkce a proměnné
Diagnostické funkce objektů
Tato makra a funkce jsou k dispozici pro všechny třídy odvozené z CObject
ladicí a vydané verze MFC. Všechny kromě DEBUG_NEW a VERIFY v verzi vydané verze nic neudělá.
V knihovně Ladění jsou všechny přidělené bloky paměti závorky s řadou "bajtů ochrany". Pokud jsou tyto bajty narušeny zápisem do paměti, můžou diagnostické rutiny ohlásit problém. Pokud zahrnete řádek:
#define new DEBUG_NEW
ve vašem implementačním souboru budou všechna volání new
ukládat název souboru a číslo řádku, kde proběhlo přidělení paměti. Funkce CMemoryState::D umpAllObjectsSince zobrazí tyto dodatečné informace, což vám umožní identifikovat nevracení paměti. Další informace o výstupu diagnostiky najdete také ve třídě CDumpContext .
Kromě toho knihovna runtime jazyka C podporuje také sadu diagnostických funkcí, které můžete použít k ladění aplikací. Další informace naleznete v tématu Rutiny ladění v referenční dokumentaci knihovny za běhu.
Obecná diagnostická makra MFC
Název | Popis |
---|---|
TVRDIT | Vytiskne zprávu a potom program přeruší, pokud se zadaný výraz vyhodnotí jako NEPRAVDA ve verzi ladění knihovny. |
ASSERT_KINDOF | Testuje, že objekt je objektem zadané třídy nebo třídy odvozené ze zadané třídy. |
ASSERT_VALID | Testuje vnitřní platnost objektu voláním jeho AssertValid členské funkce; obvykle přepsáno z CObject . |
DEBUG_NEW | Poskytuje název souboru a číslo řádku pro všechna přidělení objektů v režimu ladění, aby pomohl najít nevracení paměti. |
DEBUG_ONLY | Podobá se assert, ale neotestuje hodnotu výrazu; užitečné pro kód, který by se měl spouštět pouze v režimu ladění. |
ZAJIŠTĚNÍ a ENSURE_VALID | Slouží k ověření správnosti dat. |
THIS_FILE | Rozbalí název kompilovaného souboru. |
STOPA | Poskytuje printf funkci ladicí verze knihovny. |
OVĚŘIT | Podobá se výrazu ASSERT, ale vyhodnocuje výraz ve verzi vydané knihovny i v ladicí verzi. |
Obecné diagnostické proměnné a funkce MFC
Název | Popis |
---|---|
afxDump | Globální proměnná, která odesílá informace CDumpContext do výstupního okna ladicího programu nebo do terminálu ladění. |
afxMemDF | Globální proměnná, která řídí chování alokátoru paměti ladění. |
AfxCheckError | Globální proměnná použitá k otestování předaného SCODE, aby se zjistilo, jestli se jedná o chybu, a pokud ano, vyvolá příslušnou chybu. |
AfxCheckMemory | Kontroluje integritu všech aktuálně přidělených paměti. |
AfxDebugBreak | Způsobí přerušení provádění. |
AfxDump | Pokud je volána v ladicím programu, vysadí stav objektu během ladění. |
AfxDump | Vnitřní funkce, která při ladění vysadí stav objektu. |
AfxDumpStack | Vygenerujte obrázek aktuálního zásobníku. Tato funkce je vždy propojena staticky. |
AfxEnableMemoryLeakDump | Povolí výpis paměti nevracení paměti. |
AfxEnableMemoryTracking | Zapne a vypne sledování paměti. |
AfxIsMemoryBlock | Ověřuje, že blok paměti byl správně přidělen. |
AfxIsValidAddress | Ověřuje, že rozsah adres paměti je v mezích programu. |
AfxIsValidString | Určuje, zda je ukazatel na řetězec platný. |
AfxSetAllocHook | Umožňuje volání funkce pro každé přidělení paměti. |
Diagnostické funkce objektů MFC
Název | Popis |
---|---|
AfxDoForAllClasses | Provede zadanou funkci pro všechny CObject odvozené třídy, které podporují kontrolu typů za běhu. |
AfxDoForAllObjects | Provede zadanou funkci u všech CObject odvozených objektů, které byly přiděleny new . |
Makra kompilace MFC
Název | Popis |
---|---|
_AFX_SECURE_NO_WARNINGS | Potlačí upozornění kompilátoru pro použití zastaralých funkcí MFC. |
_AFX_SECURE_NO_WARNINGS
Potlačí upozornění kompilátoru pro použití zastaralých funkcí MFC.
Syntaxe
_AFX_SECURE_NO_WARNINGS
Příklad
Tato ukázka kódu způsobí upozornění kompilátoru, pokud _AFX_SECURE_NO_WARNINGS
není definováno.
// 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
Voláním této funkce dojde k přerušení (v umístění volání AfxDebugBreak
) při provádění ladicí verze vaší aplikace MFC.
Syntaxe
void AfxDebugBreak( );
Poznámky
AfxDebugBreak
nemá žádný vliv na verze aplikace MFC a mělo by být odebráno. Tato funkce by se měla používat pouze v aplikacích MFC. Použijte verzi rozhraní API Win32, DebugBreak
která způsobí přerušení aplikací mimo MFC.
Požadavky
Hlavička: afxver_.h
TVRDIT
Vyhodnotí jeho argument.
ASSERT(booleanExpression)
Parametry
booleanExpression
Určuje výraz (včetně hodnot ukazatele), který se vyhodnotí jako nenulový nebo 0.
Poznámky
Pokud je výsledek 0, makro vytiskne diagnostickou zprávu a program přeruší. Pokud je podmínka nenulová, nic nedělá.
Diagnostická zpráva má tvar
assertion failed in file <name> in line <num>
where name is the name of the source file, and num is the line number of the assertion that failed in the source file.
Ve verzi prostředí MFC verze ASSERT nevyhodnocuje výraz, a proto program nepřeruší. Pokud se výraz musí vyhodnotit bez ohledu na prostředí, použijte místo ASSERT makro VERIFY.
Poznámka:
Tato funkce je k dispozici pouze v ladicí verzi knihovny MFC.
Příklad
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*.
Požadavky
Hlavička: afx.h
ASSERT_KINDOF
Toto makro tvrdí, že objekt, na který odkazuje, je objektem zadané třídy nebo je objekt třídy odvozený ze zadané třídy.
ASSERT_KINDOF(classname, pobject)
Parametry
classname
Název CObject
odvozené třídy.
objekt pobject
Ukazatel na objekt třídy.
Poznámky
Parametr pobject by měl být ukazatel na objekt a může být const
. Objekt odkazovaný na třídu a třída musí podporovat CObject
informace o třídě za běhu. Pokud chcete například zajistit, aby pDocument
byl ukazatel na objekt CMyDoc
třídy nebo jakýkoli z jeho derivátů, mohli byste kód:
ASSERT_KINDOF(CMyDoc, pDocument);
ASSERT_KINDOF
Použití makra je úplně stejné jako kódování:
ASSERT(pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
Tato funkce funguje pouze pro třídy deklarované pomocí makra [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic nebo DECLARE_SERIAL makrem.
Poznámka:
Tato funkce je k dispozici pouze v ladicí verzi knihovny MFC.
Požadavky
Hlavička: afx.h
ASSERT_VALID
Slouží k otestování předpokladů o platnosti interního stavu objektu.
ASSERT_VALID(pObject)
Parametry
objekt pObject
Určuje objekt třídy odvozené z CObject
toho, který má přepsání verze AssertValid
členské funkce.
Poznámky
ASSERT_VALID volá AssertValid
členovou funkci objektu předaného jako argument.
V prostředí MFC verze ASSERT_VALID nic nedělá. Ve verzi Debug ověří ukazatel, zkontroluje hodnotu NULL a volá vlastní AssertValid
členské funkce objektu. Pokud některý z těchto testů selže, zobrazí se zpráva upozornění stejným způsobem jako ASSERT.
Poznámka:
Tato funkce je k dispozici pouze v ladicí verzi knihovny MFC.
Další informace a příklady naleznete v tématu Ladění aplikací MFC.
Příklad
// Assure that pMyObject is a valid pointer to an
// object derived from CObject.
ASSERT_VALID(pMyObject);
Požadavky
Hlavička: afx.h
DEBUG_NEW
Pomáhá při hledání nevrácené paměti.
#define new DEBUG_NEW
Poznámky
DEBUG_NEW můžete použít všude ve svém programu, který byste obvykle použili new
k přidělení úložiště haldy.
V režimu ladění (pokud je definován symbol _DEBUG ), DEBUG_NEW sleduje název souboru a číslo řádku pro každý objekt, který přidělí. Když pak použijete členovou funkci CMemoryState::D umpAllObjectsSince , zobrazí se každý objekt přidělený DEBUG_NEW s názvem souboru a číslem řádku, kde byla přidělena.
Pokud chcete použít DEBUG_NEW, vložte do zdrojových souborů následující direktivu:
#define new DEBUG_NEW
Jakmile vložíte tuto direktivu, preprocesor vloží DEBUG_NEW všude, kde použijete new
, a prostředí MFC provede zbytek. Když zkompilujete verzi programu, DEBUG_NEW přeloží na jednoduchou new
operaci a vygenerují se informace o názvu souboru a čísle řádku.
Poznámka:
V předchozích verzích mfc (4.1 a starších) jste potřebovali příkaz vložit #define
za všechny příkazy, které volaly IMPLEMENT_DYNCREATE nebo IMPLEMENT_SERIAL makra. Toto nastavení však již není nezbytné.
Požadavky
Hlavička: afx.h
DEBUG_ONLY
V režimu ladění (pokud je definován symbol _DEBUG ), DEBUG_ONLY vyhodnotí jeho argument.
DEBUG_ONLY(expression)
Poznámky
V sestavení vydané verze DEBUG_ONLY nevyhodnocuje svůj argument. To je užitečné v případě, že máte kód, který by se měl spouštět pouze v buildech ladění.
Makro DEBUG_ONLY odpovídá okolnímu výrazu s #ifdef _DEBUG
a #endif
.
Příklad
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');
}
Požadavky
Hlavička: afx.h
ZAJIŠTĚNÍ a ENSURE_VALID
Slouží k ověření správnosti dat.
Syntaxe
ENSURE( booleanExpression )
ENSURE_VALID( booleanExpression )
Parametry
booleanExpression
Určuje logický výraz, který se má testovat.
Poznámky
Účelem těchto maker je zlepšit ověřování parametrů. Makra brání dalšímu zpracování nesprávných parametrů v kódu. Na rozdíl od maker ASSERT vyvolá makra ENSURE kromě generování kontrolního výrazu výjimku.
Makra se chovají dvěma způsoby podle konfigurace projektu. Makra volají ASSERT a poté vyvolá výjimku, pokud kontrolní výraz selže. Proto v konfiguracích ladění (to znamená, že _DEBUG je definován) makra vytvářejí kontrolní výraz a výjimku v konfiguracích vydané verze, makra vytvoří pouze výjimku (ASSERT nevyhodnocuje výraz v konfiguracích vydané verze).
Makro ENSURE_ARG funguje jako makro ENSURE.
ENSURE_VALID volá makro ASSERT_VALID (které má účinek pouze v buildech ladění). Kromě toho ENSURE_VALID vyvolá výjimku, pokud je ukazatel NULL. Test NULL se provádí v konfiguraci ladění i verze.
Pokud některý z těchto testů selže, zobrazí se zpráva upozornění stejným způsobem jako ASSERT. Makro v případě potřeby vyvolá neplatnou výjimku argumentu.
Požadavky
Hlavička: afx.h
THIS_FILE
Rozbalí název kompilovaného souboru.
Syntaxe
THIS_FILE
Poznámky
Informace používají makra ASSERT a VERIFY. Průvodce aplikací a průvodci kódem umístí makro do souborů zdrojového kódu, které vytvoří.
Příklad
#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.
Požadavky
Hlavička: afx.h
TRACE
Odešle zadaný řetězec do ladicího programu aktuální aplikace.
TRACE(exp)
TRACE(DWORD category, UINT level, LPCSTR lpszFormat, ...)
Poznámky
Popis funkce TRACE najdete v ATLTRACE2 . Funkce TRACE a ATLTRACE2 mají stejné chování.
Ve verzi ladění MFC toto makro odešle zadaný řetězec do ladicího programu aktuální aplikace. V sestavení vydané verze se toto makro zkompiluje na nic (vůbec se negeneruje žádný kód).
Další informace naleznete v tématu Ladění aplikací MFC.
Požadavky
Hlavička: afx.h
OVĚŘIT
V ladicí verzi mfc vyhodnotí jeho argument.
VERIFY(booleanExpression)
Parametry
booleanExpression
Určuje výraz (včetně hodnot ukazatele), který se vyhodnotí jako nenulový nebo 0.
Poznámky
Pokud je výsledek 0, makro vytiskne diagnostickou zprávu a program zastaví. Pokud je podmínka nenulová, nic nedělá.
Diagnostická zpráva má tvar
assertion failed in file <name> in line <num>
where name is the name of the source file and num is the line number of the assertion that failed in the source file.
Ve verzi prostředí MFC verze funkce VERIFY vyhodnotí výraz, ale netiskne nebo přeruší program. Pokud je například výraz voláním funkce, bude volání provedeno.
Příklad
// 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);
Požadavky
Hlavička: afx.h
afxDump (CDumpContext v prostředí MFC)
Poskytuje základní možnosti dumpingu objektů ve vaší aplikaci.
CDumpContext afxDump;
Poznámky
afxDump
je předdefinovaný objekt CDumpContext , který umožňuje odesílat CDumpContext
informace do výstupního okna ladicího programu nebo do ladicího terminálu. Obvykle zadáte afxDump
jako parametr .CObject::Dump
V části systém Windows NT a všechny verze Systému Windows afxDump
se výstup odešle do okna Výstup-Ladění jazyka Visual C++ při ladění aplikace.
Tato proměnná je definována pouze v ladicí verzi mfc. Další informace naleznete v afxDump
tématu Ladění aplikací MFC.
Příklad
// 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
Požadavky
Hlavička: afx.h
AfxDump (interní)
Interní funkce, kterou MFC používá k výpisu stavu objektu při ladění
Syntaxe
void AfxDump(const CObject* pOb);
Parametry
Pob
Ukazatel na objekt třídy odvozené od CObject
.
Poznámky
AfxDump
volá členskou funkci objektu Dump
a odesílá informace do umístění určeného proměnnou afxDump
. AfxDump
je k dispozici pouze v ladicí verzi knihovny MFC.
Kód programu by neměl volat AfxDump
, ale měl by místo toho volat Dump
člen funkce příslušného objektu.
Požadavky
Hlavička: afx.h
afxMemDF
Tato proměnná je přístupná z ladicího programu nebo programu a umožňuje ladit diagnostiku přidělení.
int afxMemDF;
Poznámky
afxMemDF
může mít následující hodnoty, jak je určeno výčtem afxMemDF
:
allocMemDF
Zapne alokátor ladění (výchozí nastavení v knihovně ladění).delayFreeMemDF
Zpožďuje uvolnění paměti. I když program uvolní blok paměti, alokátor nevrátí danou paměť do základního operačního systému. Tím dojde k maximálnímu zatížení paměti ve vašem programu.checkAlwaysMemDF
VoláníAfxCheckMemory
při každém přidělení nebo uvolnění paměti. Tím se výrazně zpomalí přidělení a přidělení paměti.
Příklad
afxMemDF = allocMemDF | checkAlwaysMemDF;
Požadavky
Hlavička: afx.h
AfxCheckError
Tato funkce testuje předaný kód SCODE a zjistí, jestli se jedná o chybu.
void AFXAPI AfxCheckError(SCODE sc);
throw CMemoryException*
throw COleException*
Poznámky
Pokud se jedná o chybu, funkce vyvolá výjimku. Pokud je předaný kód SCODE E_OUTOFMEMORY, funkce vyvolá CMemoryException voláním AfxThrowMemoryException. V opačném případě funkce vyvolá COleException voláním AfxThrowOleException.
Tuto funkci lze použít ke kontrole vrácených hodnot volání funkcí OLE ve vaší aplikaci. Testováním návratové hodnoty pomocí této funkce v aplikaci můžete správně reagovat na chybové stavy s minimálním množstvím kódu.
Poznámka:
Tato funkce má stejný účinek v sestaveních ladění a neladit.
Příklad
AfxCheckError(::CoCreateInstance(clsidWMP, NULL, CLSCTX_INPROC_SERVER,
IID_IDispatch, (LPVOID*)& pWMPDispatch));
oddWMP.AttachDispatch(pWMPDispatch, TRUE);
Požadavky
Hlavička: afx.h
AfxCheckMemory
Tato funkce ověří volný fond paměti a podle potřeby vytiskne chybové zprávy.
BOOL AfxCheckMemory();
Návratová hodnota
Nenulové, pokud žádné chyby paměti; jinak 0.
Poznámky
Pokud funkce nezjistí poškození paměti, vytiskne nic.
Zkontrolují se všechny bloky paměti, které new
jsou aktuálně přidělené haldě, včetně bloků přidělených přímo voláním základních přidělení paměti, jako je malloc nebo GlobalAlloc
funkce Windows. Pokud dojde k poškození nějakého bloku, vytiskne se do výstupu ladicího programu zpráva.
Pokud zahrnete řádek
#define new DEBUG_NEW
v programovém modulu pak následná volání zobrazte AfxCheckMemory
název souboru a číslo řádku, kde byla paměť přidělena.
Poznámka:
Pokud váš modul obsahuje jednu nebo více implementací serializovatelných tříd, je nutné vložit #define
řádek za poslední IMPLEMENT_SERIAL volání makra.
Tato funkce funguje pouze v ladicí verzi knihovny MFC.
Příklad
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();
Požadavky
Hlavička: afx.h
AfxDump (MFC)
Volání této funkce v ladicím programu k výpisu stavu objektu při ladění.
void AfxDump(const CObject* pOb);
Parametry
Pob
Ukazatel na objekt třídy odvozené od CObject
.
Poznámky
AfxDump
volá členskou funkci objektu Dump
a odesílá informace do umístění určeného proměnnou afxDump
. AfxDump
je k dispozici pouze v ladicí verzi knihovny MFC.
Kód programu by neměl volat AfxDump
, ale měl by místo toho volat Dump
člen funkce příslušného objektu.
Požadavky
Hlavička: afx.h
AfxDumpStack
Tuto globální funkci lze použít k vygenerování obrázku aktuálního zásobníku.
void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);
Parametry
dwTarget
Označuje cíl výstupu výpisu paměti. Možné hodnoty, které lze kombinovat pomocí bitového operátoru OR (|
) jsou následující:
AFX_STACK_DUMP_TARGET_TRACE Odešle výstup pomocí makra TRACE . Makro TRACE generuje výstup pouze v buildech ladění; v buildech vydaných verzí nevygeneruje žádný výstup. Trasování je také možné přesměrovat na jiné cíle kromě ladicího programu.
AFX_STACK_DUMP_TARGET_DEFAULT Odešle výstup výpisu do výchozího cíle. Pro sestavení ladění přejde výstup do makra TRACE. V buildu vydané verze se výstup vrátí do schránky.
AFX_STACK_DUMP_TARGET_CLIPBOARD Odesílá výstup pouze do schránky. Data jsou ve schránce umístěna jako prostý text ve formátu CF_TEXT Schránka.
AFX_STACK_DUMP_TARGET_BOTH Odešle výstup do schránky a do makra TRACE současně.
AFX_STACK_DUMP_TARGET_ODS Odešle výstup přímo do ladicího programu pomocí funkce
OutputDebugString()
Win32 . Tato možnost vygeneruje výstup ladicího programu v sestavení ladění i vydané verze, když je k procesu připojen ladicí program. AFX_STACK_DUMP_TARGET_ODS vždy dosáhne ladicího programu (pokud je připojen) a nelze jej přesměrovat.
Poznámky
Následující příklad odráží jeden řádek výstupu vygenerovaného z volání AfxDumpStack
z obslužné rutiny tlačítka v aplikaci dialogového okna MFC:
=== 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 ===
Každý řádek ve výstupu výše označuje adresu posledního volání funkce, úplný název cesty modulu, který obsahuje volání funkce, a prototyp funkce volaný. Pokud volání funkce v zásobníku nenastane na přesné adrese funkce, zobrazí se posun bajtů.
Například následující tabulka popisuje první řádek výše uvedeného výstupu:
Výstup | Popis |
---|---|
00427D55: |
Zpáteční adresa posledního volání funkce. |
DUMP2\DEBUG\DUMP2.EXE! |
Úplný název cesty modulu, který obsahuje volání funkce. |
void AfxDumpStack(unsigned long) |
Volal se prototyp funkce. |
+ 181 bytes |
Posun v bajtech od adresy prototypu funkce (v tomto případě void AfxDumpStack(unsigned long) ) na zpáteční adresu (v tomto případě 00427D55 ). |
AfxDumpStack
je k dispozici v ladicích a nedebugovaných verzích knihoven MFC; Funkce je však vždy propojena staticky, i když spustitelný soubor používá mfc ve sdílené knihovně DLL. V implementacích sdílené knihovny se funkce nachází v prostředí MFCS42. Knihovna LIB (a její varianty).
Úspěšné použití této funkce:
Soubor IMAGEHLP.DLL musí být na vaší cestě. Pokud tuto knihovnu DLL nemáte, funkce zobrazí chybovou zprávu. Informace o sadě funkcí poskytovaných nástrojem IMAGEHLP najdete v knihovně nápovědy k obrázku.
Moduly, které mají rámce v zásobníku, musí obsahovat informace o ladění. Pokud neobsahují informace o ladění, funkce stále vygeneruje trasování zásobníku, ale trasování bude méně podrobné.
Požadavky
Hlavička: afx.h
AfxEnableMemoryLeakDump
Povolí a zakáže výpis paměti v AFX_DEBUG_STATE destruktoru.
BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);
Parametry
bDump
[v] TRUE označuje, že je povolen výpis paměti nevracení; NEPRAVDA označuje, že výpis paměti nevracení je zakázaný.
Návratová hodnota
Předchozí hodnota pro tento příznak.
Poznámky
Když aplikace uvolní knihovnu MFC, knihovna MFC zkontroluje nevracení paměti. V tomto okamžiku se uživateli hlásí případné nevracení paměti prostřednictvím okna Ladění sady Visual Studio.
Pokud vaše aplikace načte jinou knihovnu před knihovnou MFC, některé přidělení paměti v této knihovně budou nesprávně hlášeny jako nevracení paměti. Nevracení nepravdivé paměti může způsobit, že se aplikace pomalu zavře, protože je knihovna MFC hlásí. V tomto případě použijte AfxEnableMemoryLeakDump
k zakázání výpisu paměti nevracení paměti.
Poznámka:
Pokud tuto metodu použijete k vypnutí výpisu paměti nevracení paměti, nebudete ve své aplikaci dostávat zprávy o platných nevracení paměti. Tuto metodu byste měli použít pouze v případě, že máte jistotu, že sestava nevracení paměti obsahuje nevracení paměti.
Požadavky
Hlavička: afx.h
AfxEnableMemoryTracking
Sledování paměti diagnostiky je normálně povoleno ve verzi ladění mfc.
BOOL AfxEnableMemoryTracking(BOOL bTrack);
Parametry
bTrack
Nastavení této hodnoty na TRUE zapne sledování paměti; FALSE ji vypne.
Návratová hodnota
Předchozí nastavení příznaku povolení sledování
Poznámky
Pomocí této funkce můžete zakázat sledování oddílů kódu, o kterých víte, že bloky se správně oddělují.
Další informace naleznete v AfxEnableMemoryTracking
tématu Ladění aplikací MFC.
Poznámka:
Tato funkce funguje pouze v ladicí verzi knihovny MFC.
Příklad
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;
}
Požadavky
Hlavička: afx.h
AfxIsMemoryBlock
Otestuje adresu paměti, aby se ujistil, že představuje aktuálně aktivní blok paměti, který byl přidělen diagnostickou verzí new
.
BOOL AfxIsMemoryBlock(
const void* p,
UINT nBytes,
LONG* plRequestNumber = NULL);
Parametry
p
Odkazuje na blok paměti, který se má testovat.
nBajty
Obsahuje délku bloku paměti v bajtech.
plRequestNumber
Odkazuje na long
celé číslo, které bude vyplněno pořadovým číslem bloku přidělení bloku paměti nebo nulou, pokud nepředstavuje aktuálně aktivní blok paměti.
Návratová hodnota
Nenulové, pokud je blok paměti aktuálně přidělen a délka je správná; jinak 0.
Poznámky
Zkontroluje také zadanou velikost oproti původní přidělené velikosti. Pokud funkce vrátí nenulové číslo, vrátí se pořadové číslo přidělení v plRequestNumber. Toto číslo představuje pořadí, ve kterém byl blok přidělen vzhledem ke všem ostatním new
přidělením.
Příklad
CAge* pcage = new CAge(21); // CAge is derived from CObject.
ASSERT(AfxIsMemoryBlock(pcage, sizeof(CAge)));
Požadavky
Hlavička: afx.h
AfxIsValidAddress
Otestuje všechny adresy paměti, aby se zajistilo, že je zcela obsažena v paměťovém prostoru programu.
BOOL AfxIsValidAddress(
const void* lp,
UINT nBytes,
BOOL bReadWrite = TRUE);
Parametry
Lp
Odkazuje na adresu paměti, která se má testovat.
nBajty
Obsahuje počet bajtů paměti, které se mají testovat.
bReadWrite
Určuje, jestli je paměť určená pro čtení i zápis (TRUE) nebo jen pro čtení (FALSE).
Návratová hodnota
V ladicích buildech nenulové, pokud je zadaný blok paměti zcela obsažen v prostoru paměti programu; jinak 0.
V neladicích sestaveních není hodnota nenulová, pokud lp není NULL, jinak 0.
Poznámky
Adresa není omezena na bloky přidělené new
.
Příklad
// 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));
Požadavky
Hlavička: afx.h
AfxIsValidString
Tato funkce slouží k určení, zda je ukazatel na řetězec platný.
BOOL AfxIsValidString(
LPCSTR lpsz,
int nLength = -1);
Parametry
lpsz
Ukazatel, který chcete otestovat.
nLength
Určuje délku řetězce, který se má testovat, v bajtech. Hodnota -1 označuje, že řetězec bude ukončen s hodnotou null.
Návratová hodnota
V ladicích buildech nenulové, pokud zadaný ukazatel odkazuje na řetězec zadané velikosti; jinak 0.
V neladicích buildech není hodnota nenulová, pokud lpsz není NULL, jinak 0.
Příklad
// 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));
Požadavky
Hlavička: afx.h
AfxSetAllocHook
Nastaví háček, který umožňuje volání zadané funkce před přidělením každého bloku paměti.
AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);
Parametry
pfnAllocHook
Určuje název funkce, která se má volat. Podívejte se na poznámky k prototypu funkce přidělení.
Návratová hodnota
Nenulové, pokud chcete povolit přidělení; jinak 0.
Poznámky
Alokátor ladicí paměti knihovny tříd Microsoft Foundation může volat uživatelem definovanou funkci háku, která uživateli umožní monitorovat přidělení paměti a řídit, zda je přidělení povoleno. Funkce háku přidělení jsou prototypovány následujícím způsobem:
BOOL AFXAPI AllocHook( size_t nSize
, BOOLbObject
, LONG ); lRequestNumber
NSize
Velikost navrhovaného přidělení paměti.
bObject
TRUE, pokud je přidělení pro -odvozený CObject
objekt; jinak NEPRAVDA.
lRequestNumber
Pořadové číslo přidělení paměti.
Všimněte si, že konvence volání AFXAPI znamená, že volaný musí odebrat parametry ze zásobníku.
Požadavky
Hlavička: afx.h
AfxDoForAllClasses
Volá zadanou iterační funkci pro všechny serializovatelné CObject
-odvozené třídy v paměťovém prostoru aplikace.
void
AFXAPI AfxDoForAllClasses(
void (* pfn)(const CRuntimeClass* pClass, void* pContext),
void* pContext);
Parametry
pfn
Odkazuje na iterační funkci, která se má volat pro každou třídu. Argumenty funkce jsou ukazatel na CRuntimeClass
objekt a ukazatel void na další data, která volající dodává funkci.
pContext
Odkazuje na volitelná data, která volající může poskytnout funkci iterace. Tento ukazatel může mít hodnotu NULL.
Poznámky
Serializovatelné CObject
-odvozené třídy jsou třídy odvozené pomocí DECLARE_SERIAL makra. Ukazatel předaný v AfxDoForAllClasses
pContext je předán zadané iterační funkci pokaždé, když je volána.
Poznámka:
Tato funkce funguje pouze v ladicí verzi knihovny MFC.
Příklad
#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
Požadavky
Hlavička: afx.h
AfxDoForAllObjects
Spustí zadanou iterační funkci pro všechny objekty odvozené z CObject
přidělených new
.
void AfxDoForAllObjects(
void (* pfn)(CObject* pObject, void* pContext),
void* pContext);
Parametry
pfn
Odkazuje na iterační funkci, která se má provést pro každý objekt. Argumenty funkce jsou ukazatel na CObject
ukazatel a ukazatel void na nadbytečná data, která volající dodává funkci.
pContext
Odkazuje na volitelná data, která volající může poskytnout funkci iterace. Tento ukazatel může mít hodnotu NULL.
Poznámky
Zásobník, globální nebo vložené objekty se nevyčtou. Ukazatel předaný v AfxDoForAllObjects
pContext je předán zadané iterační funkci pokaždé, když je volána.
Poznámka:
Tato funkce funguje pouze v ladicí verzi knihovny MFC.
Příklad
#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