Condividi tramite


Servizi diagnostici

La libreria Microsoft Foundation Class fornisce numerosi servizi di diagnostica che semplificano il debug dei programmi. I servizi di diagnostica includono macro e funzioni globali che consentono di tenere traccia delle allocazioni della memoria del programma, scaricare il contenuto degli oggetti in fase di esecuzione e stampare i messaggi di debug in fase di esecuzione. Le macro e funzioni globali per servizi di diagnostica sono raggruppate nelle categorie seguenti:

  • Macro diagnostiche generali

  • Funzioni e variabili di diagnostica generale

  • Funzioni di diagnostica oggetti

Queste macro e funzioni sono disponibili per tutte le classi derivate da CObject nelle versioni di debug e rilascio di MFC. Tuttavia, tutti tranne DEBUG_NEW e VERIFY non eseguono alcuna operazione nella versione di rilascio.

Nella libreria debug tutti i blocchi di memoria allocati sono racchiusi tra parentesi con una serie di "byte di protezione". Se questi byte sono disturbati da una scrittura di memoria errante, le routine di diagnostica possono segnalare un problema. Se si include la riga:

#define new DEBUG_NEW

nel file di implementazione tutte le chiamate a new archivieranno il nome file e il numero di riga in cui è stata eseguita l'allocazione di memoria. La funzione CMemoryState:: DumpAllObjectsSince visualizzerà queste informazioni aggiuntive, che consentono di identificare le perdite di memoria. Per altre informazioni sull'output di diagnostica vedere anche la classe CDumpContext .

Inoltre, la libreria di runtime C supporta anche un set di funzioni di diagnostica che è possibile usare per eseguire il debug delle applicazioni. Per altre informazioni, vedere Routine di debug in Riferimenti alla libreria di runtime.

Macro diagnostiche generali in MFC

Nome Descrizione
ASSERT Stampa un messaggio e quindi arresta il programma se l'espressione specificata restituisce FALSE nella versione di debug della libreria.
ASSERT_KINDOF Verifica se un oggetto è un oggetto della classe specificata o di una classe derivata dalla classe specificata.
ASSERT_VALID Verifica la validità interna di un oggetto chiamando la relativa funzione membro AssertValid ; in genere sottoposta a override da CObject.
DEBUG_NEW Fornisce un nome file e un numero di riga per tutte le allocazioni di oggetti in modalità di debug per trovare perdite di memoria.
DEBUG_ONLY Simile ad ASSERT ma non verifica il valore dell'espressione; utile per il codice che deve essere eseguito solo in modalità di debug.
ENSURE e ENSURE_VALID Usare per convalidare la correttezza dei dati.
THIS_FILE Espande fino al nome del file in fase di compilazione.
TRACE Fornisce una funzionalità simile a printf-nella versione di debug della libreria.
VERIFY Simile ad ASSERT ma valuta l'espressione nella versione di rilascio della libreria oltre che nella versione di debug.

Funzioni e variabili di diagnostica generale in MFC

Nome Descrizione
afxDump Variabile globale che invia informazioni CDumpContext alla finestra di output o al terminale di debug.
afxMemDF Variabile globale che controlla il comportamento dell'allocatore di memoria di debug.
AfxCheckError Variabile globale usata per verificare l'oggetto SCODE passato per verificare se è un errore; in caso affermativo, genera l'errore appropriato.
AfxCheckMemory Controlla l'integrità di tutta la memoria attualmente allocata.
AfxDebugBreak Causa un'interruzione nell'esecuzione.
AfxDump Se viene chiamato quando nel debugger, esegue il dump dello stato di un oggetto durante il debug.
AfxDump Funzione interna che esegue il dump dello stato di un oggetto durante il debug.
AfxDumpStack Genera un'immagine dello stack corrente. Questa funzione è sempre collegata staticamente.
AfxEnableMemoryLeakDump Consente il dump della perdita di memoria.
AfxEnableMemoryTracking Attiva e disattiva rilevamento della memoria.
AfxIsMemoryBlock Verifica che un blocco di memoria sia stato allocato in modo corretto.
AfxIsValidAddress Verifica che un intervallo di indirizzi di memoria si trovi all'interno dei limiti del programma.
AfxIsValidString Determina se un puntatore a una stringa è valido.
AfxSetAllocHook Consente la chiamata di una funzione in ogni allocazione di memoria.

Funzioni di diagnostica oggetti in MFC

Nome Descrizione
AfxDoForAllClasses Esegue una funzione specificata su tutte le classi derivate da CObjectche supportano il controllo del tipo in fase di esecuzione.
AfxDoForAllObjects Esegue una funzione specificata su tutti gli CObjectoggetti derivati da che sono stati allocati con new.

Macro di compilazione MFC

Nome Descrizione
_AFX_SECURE_NO_WARNINGS Elimina gli avvisi del compilatore per l'uso di funzioni MFC deprecate.

_AFX_SECURE_NO_WARNINGS

Elimina gli avvisi del compilatore per l'uso di funzioni MFC deprecate.

Sintassi

_AFX_SECURE_NO_WARNINGS

Esempio

Questo esempio di codice genera un avviso del compilatore se _AFX_SECURE_NO_WARNINGS non è definito.

// 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

Chiamare questa funzione per causare un'interruzione (nella posizione della chiamata a AfxDebugBreak) nell'esecuzione della versione di debug dell'applicazione MFC.

Sintassi

void AfxDebugBreak( );

Osservazioni:

AfxDebugBreak non ha alcun effetto nelle versioni di rilascio di un'applicazione MFC e deve essere rimosso. Questa funzione deve essere usata solo nelle applicazioni MFC. Usare la versione dell'API Win32, DebugBreak, per causare un'interruzione nelle applicazioni non MFC.

Requisiti

Intestazione: afxver_.h

ASSERT

Valuta il relativo argomento.

ASSERT(booleanExpression)

Parametri

booleanExpression
Specifica un'espressione (inclusi i valori del puntatore) che restituisce un valore diverso da zero o 0.

Osservazioni:

Se il risultato è 0, la macro stampa un messaggio di diagnostica e interrompe il programma. Se la condizione è diversa da zero, non esegue alcuna operazione.

Il messaggio di diagnostica presenta la forma seguente:

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

dove name è il nome del file di origine e num è il numero di riga dell'asserzione non riuscita nel file di origine.

Nella versione release di MFC ASSERT non valuta l'espressione e pertanto non interromperà il programma. Se l'espressione deve essere valutata indipendentemente dall'ambiente, usare la macro VERIFY al posto di ASSERT.

Nota

Questa funzione è disponibile solo nella versione Debug di MFC.

Esempio

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*.   

Requisiti

Intestazione: afx.h

ASSERT_KINDOF

Questa macro afferma che l'oggetto a cui punta è un oggetto della classe specificata o è un oggetto di una classe derivata dalla classe specificata.

ASSERT_KINDOF(classname, pobject)

Parametri

nomeclasse
Nome di una CObjectclasse derivata da .

pobject
Puntatore a un oggetto classe.

Osservazioni:

Il parametro pobject deve essere un puntatore a un oggetto e può essere const. L'oggetto a cui punta e la classe deve supportare CObject le informazioni sulla classe di runtime. Ad esempio, per assicurarsi che pDocument sia un puntatore a un oggetto della CMyDoc classe o a uno dei relativi derivati, è possibile codificare:

ASSERT_KINDOF(CMyDoc, pDocument);

L'uso della ASSERT_KINDOF macro equivale esattamente alla codifica:

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

Questa funzione funziona solo per le classi dichiarate con la macro [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic o DECLARE_SERIAL .

Nota

Questa funzione è disponibile solo nella versione Debug di MFC.

Requisiti

Intestazione: afx.h

ASSERT_VALID

Usare per testare i presupposti sulla validità dello stato interno di un oggetto.

ASSERT_VALID(pObject)

Parametri

pObject
Specifica un oggetto di una classe derivata da CObject che ha una versione di override della AssertValid funzione membro.

Osservazioni:

ASSERT_VALID chiama la AssertValid funzione membro dell'oggetto passato come argomento.

Nella versione release di MFC ASSERT_VALID non esegue alcuna operazione. Nella versione di debug convalida il puntatore, verifica la presenza di VALORI NULL e chiama le funzioni AssertValid membro dell'oggetto. Se uno di questi test ha esito negativo, viene visualizzato un messaggio di avviso nello stesso modo di ASSERT.

Nota

Questa funzione è disponibile solo nella versione Debug di MFC.

Per altre informazioni ed esempi, vedere Debug di applicazioni MFC.

Esempio

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

Requisiti

Intestazione: afx.h

DEBUG_NEW

Aiuta a trovare perdite di memoria.

#define  new DEBUG_NEW

Osservazioni:

È possibile usare DEBUG_NEW ovunque nel programma che si userebbe normalmente l'operatore per allocare l'archiviazione dell'heap new .

In modalità di debug (quando viene definito il simbolo di _DEBUG ), DEBUG_NEW tiene traccia del nome file e del numero di riga per ogni oggetto allocato. Quindi, quando si usa la funzione membro CMemoryState::D umpAllObjectsSince , ogni oggetto allocato con DEBUG_NEW viene visualizzato con il nome file e il numero di riga in cui è stato allocato.

Per usare DEBUG_NEW, inserire la direttiva seguente nei file di origine:

#define new DEBUG_NEW

Dopo aver inserito questa direttiva, il preprocessore inserisce DEBUG_NEW ovunque si usi newe MFC esegue il resto. Quando si compila una versione di rilascio del programma, DEBUG_NEW si risolve in un'operazione semplice new e le informazioni sul nome file e sul numero di riga non vengono generate.

Nota

Nelle versioni precedenti di MFC (4.1 e versioni precedenti) è necessario inserire l'istruzione #define dopo tutte le istruzioni che hanno chiamato le macro IMPLEMENT_DYNCREATE o IMPLEMENT_SERIAL. Questa operazione non è più necessaria.

Requisiti

Intestazione: afx.h

DEBUG_ONLY

In modalità di debug (quando viene definito il simbolo di _DEBUG ), DEBUG_ONLY valuta il relativo argomento.

DEBUG_ONLY(expression)

Osservazioni:

In una build di versione, DEBUG_ONLY non valuta il relativo argomento. Ciò è utile quando si dispone di codice che deve essere eseguito solo nelle compilazioni di debug.

La macro DEBUG_ONLY equivale all'espressione circostante con #ifdef _DEBUG e #endif.

Esempio

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');
}

Requisiti

Intestazione: afx.h

ENSURE e ENSURE_VALID

Usare per convalidare la correttezza dei dati.

Sintassi

ENSURE(  booleanExpression )
ENSURE_VALID( booleanExpression  )

Parametri

booleanExpression
Specifica un'espressione booleana da testare.

Osservazioni:

Lo scopo di queste macro è migliorare la convalida dei parametri. Le macro impediscono un'ulteriore elaborazione di parametri non corretti nel codice. A differenza delle macro ASSERT, le macro ENSURE generano un'eccezione oltre a generare un'asserzione.

Le macro si comportano in due modi, in base alla configurazione del progetto. Le macro chiamano ASSERT e quindi generano un'eccezione se l'asserzione non riesce. Pertanto, nelle configurazioni di debug (ovvero, dove è definito _DEBUG) le macro producono un'asserzione ed eccezione mentre nelle configurazioni release le macro producono solo l'eccezione (ASSERT non valuta l'espressione nelle configurazioni release).

La macro ENSURE_ARG agisce come la macro ENSURE.

ENSURE_VALID chiama la macro ASSERT_VALID (che ha un effetto solo nelle compilazioni di debug). Inoltre, ENSURE_VALID genera un'eccezione se il puntatore è NULL. Il test NULL viene eseguito sia nelle configurazioni di debug che di rilascio.

Se uno di questi test ha esito negativo, viene visualizzato un messaggio di avviso nello stesso modo di ASSERT. Se necessario, la macro genera un'eccezione di argomento non valida.

Requisiti

Intestazione: afx.h

THIS_FILE

Espande fino al nome del file in fase di compilazione.

Sintassi

THIS_FILE

Osservazioni:

Le informazioni vengono utilizzate dalle macro ASSERT e VERIFY. La Creazione guidata applicazione e le procedure guidate di codice inseriscono la macro nei file di codice sorgente creati.

Esempio

#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.

Requisiti

Intestazione: afx.h

TRACE

Invia la stringa specificata al debugger dell'applicazione corrente.

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

Osservazioni:

Per una descrizione di TRACE, vedere ATLTRACE2 . TRACE e ATLTRACE2 hanno lo stesso comportamento.

Nella versione di debug di MFC questa macro invia la stringa specificata al debugger dell'applicazione corrente. In una build di versione, questa macro viene compilata in nulla (non viene generato alcun codice).

Per altre informazioni, vedere Debug di applicazioni MFC.

Requisiti

Intestazione: afx.h

VERIFY

Nella versione debug di MFC valuta il relativo argomento.

VERIFY(booleanExpression)

Parametri

booleanExpression
Specifica un'espressione (inclusi i valori del puntatore) che restituisce un valore diverso da zero o 0.

Osservazioni:

Se il risultato è 0, la macro stampa un messaggio di diagnostica e interrompe il programma. Se la condizione è diversa da zero, non esegue alcuna operazione.

Il messaggio di diagnostica presenta la forma seguente:

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

dove name è il nome del file di origine e num è il numero di riga dell'asserzione non riuscita nel file di origine.

Nella versione release di MFC, VERIFY valuta l'espressione ma non stampa o interrompe il programma. Ad esempio, se l'espressione è una chiamata di funzione, verrà eseguita la chiamata.

Esempio

// 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);

Requisiti

Intestazione: afx.h

afxDump (CDumpContext in MFC)

Fornisce funzionalità di base per il dump di oggetti nell'applicazione.

CDumpContext  afxDump;

Osservazioni:

afxDumpè un oggetto CDumpContext predefinito che consente di inviare CDumpContext informazioni alla finestra di output del debugger o a un terminale di debug. In genere, si specifica afxDump come parametro a CObject::Dump.

In Windows NT e in tutte le versioni di Windows, afxDump l'output viene inviato alla finestra Output-Debug di Visual C++ quando si esegue il debug dell'applicazione.

Questa variabile è definita solo nella versione Debug di MFC. Per altre informazioni su afxDump, vedere Debug di applicazioni MFC.

Esempio

// 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

Requisiti

Intestazione: afx.h

AfxDump (interno)

Funzione interna usata da MFC per eseguire il dump dello stato di un oggetto durante il debug.

Sintassi

void AfxDump(const CObject* pOb);

Parametri

Pob
Puntatore a un oggetto di una classe derivata da CObject.

Osservazioni:

AfxDump chiama la funzione membro di Dump un oggetto e invia le informazioni alla posizione specificata dalla afxDump variabile. AfxDump è disponibile solo nella versione debug di MFC.

Il codice del programma non deve chiamare AfxDump, ma deve invece chiamare la Dump funzione membro dell'oggetto appropriato.

Requisiti

Intestazione: afx.h

afxMemDF

Questa variabile è accessibile da un debugger o dal programma e consente di ottimizzare la diagnostica dell'allocazione.

int  afxMemDF;

Osservazioni:

afxMemDF può avere i valori seguenti, come specificato dall'enumerazione afxMemDF:

  • allocMemDF Attiva il debug dell'allocatore (impostazione predefinita nella libreria di debug).

  • delayFreeMemDF Ritarda la liberazione della memoria. Mentre il programma libera un blocco di memoria, l'allocatore non restituisce tale memoria al sistema operativo sottostante. In questo modo, lo stress di memoria massimo verrà posto sul programma.

  • checkAlwaysMemDF Chiama AfxCheckMemory ogni volta che la memoria viene allocata o liberata. Ciò rallenta significativamente le allocazioni di memoria e le deallocazione.

Esempio

afxMemDF = allocMemDF | checkAlwaysMemDF;

Requisiti

Intestazione: afx.h

AfxCheckError

Questa funzione verifica il codice SCODE passato per verificare se si tratta di un errore.

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

Osservazioni:

Se si tratta di un errore, la funzione genera un'eccezione. Se l'oggetto SCODE passato è E_OUTOFMEMORY, la funzione genera un'eccezione CMemoryException chiamando AfxThrowMemoryException. In caso contrario, la funzione genera un'eccezione COleException chiamando AfxThrowOleException.

Questa funzione può essere usata per controllare i valori restituiti delle chiamate alle funzioni OLE nell'applicazione. Testando il valore restituito con questa funzione nell'applicazione, è possibile reagire correttamente alle condizioni di errore con una quantità minima di codice.

Nota

Questa funzione ha lo stesso effetto nelle compilazioni di debug e non di debug.

Esempio

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

oddWMP.AttachDispatch(pWMPDispatch, TRUE);

Requisiti

Intestazione: afx.h

AfxCheckMemory

Questa funzione convalida il pool di memoria libera e stampa i messaggi di errore in base alle esigenze.

BOOL  AfxCheckMemory();

Valore restituito

Diverso da zero se non sono presenti errori di memoria; in caso contrario, 0.

Osservazioni:

Se la funzione non rileva alcun danneggiamento della memoria, non stampa nulla.

Tutti i blocchi di memoria attualmente allocati nell'heap vengono controllati, inclusi quelli allocati da new ma non da quelli allocati dalle chiamate dirette agli allocatori di memoria sottostanti, ad esempio la funzione malloc o la GlobalAlloc funzione Windows. Se viene rilevato un blocco danneggiato, viene stampato un messaggio nell'output del debugger.

Se si include la riga

#define new DEBUG_NEW

in un modulo di programma, quindi chiamate successive per AfxCheckMemory visualizzare il nome file e il numero di riga in cui è stata allocata la memoria.

Nota

Se il modulo contiene una o più implementazioni di classi serializzabili, è necessario inserire la #define riga dopo l'ultima chiamata di macro IMPLEMENT_SERIAL.

Questa funzione funziona solo nella versione Debug di MFC.

Esempio

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();

Requisiti

Intestazione: afx.h

AfxDump (MFC)

Chiamare questa funzione mentre si trova nel debugger per eseguire il dump dello stato di un oggetto durante il debug.

void AfxDump(const CObject* pOb);

Parametri

Pob
Puntatore a un oggetto di una classe derivata da CObject.

Osservazioni:

AfxDump chiama la funzione membro di Dump un oggetto e invia le informazioni alla posizione specificata dalla afxDump variabile. AfxDump è disponibile solo nella versione debug di MFC.

Il codice del programma non deve chiamare AfxDump, ma deve invece chiamare la Dump funzione membro dell'oggetto appropriato.

Requisiti

Intestazione: afx.h

AfxDumpStack

Questa funzione globale può essere usata per generare un'immagine dello stack corrente.

void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);

Parametri

dwTarget
Indica la destinazione dell'output del dump. I valori possibili, che possono essere combinati usando l'operatore OR bit per bit (|), sono i seguenti:

  • AFX_STACK_DUMP_TARGET_TRACE Invia l'output tramite la macro TRACE . La macro TRACE genera l'output solo nelle compilazioni di debug; non genera alcun output nelle build di versione. Inoltre, TRACE può essere reindirizzato ad altre destinazioni oltre al debugger.

  • AFX_STACK_DUMP_TARGET_DEFAULT Invia l'output del dump alla destinazione predefinita. Per una compilazione di debug, l'output passa alla macro TRACE. In una build di versione, l'output passa agli Appunti.

  • AFX_STACK_DUMP_TARGET_CLIPBOARD Invia l'output solo agli Appunti. I dati vengono inseriti negli Appunti come testo normale usando il formato CF_TEXT Appunti.

  • AFX_STACK_DUMP_TARGET_BOTH Invia l'output agli Appunti e alla macro TRACE contemporaneamente.

  • AFX_STACK_DUMP_TARGET_ODS Invia l'output direttamente al debugger tramite la funzione OutputDebugString()Win32 . Questa opzione genererà l'output del debugger nelle compilazioni di debug e versione quando un debugger è collegato al processo. AFX_STACK_DUMP_TARGET_ODS raggiunge sempre il debugger (se è collegato) e non può essere reindirizzato.

Osservazioni:

L'esempio seguente riflette una singola riga dell'output generato dalla chiamata AfxDumpStack da un gestore di pulsanti in un'applicazione di dialogo 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 ===

Ogni riga nell'output precedente indica l'indirizzo dell'ultima chiamata di funzione, il nome del percorso completo del modulo che contiene la chiamata di funzione e il prototipo di funzione chiamato. Se la chiamata di funzione nello stack non si verifica all'indirizzo esatto della funzione, viene visualizzato un offset di byte.

Ad esempio, la tabella seguente descrive la prima riga dell'output precedente:

Output Descrizione
00427D55: Indirizzo restituito dell'ultima chiamata di funzione.
DUMP2\DEBUG\DUMP2.EXE! Nome del percorso completo del modulo che contiene la chiamata di funzione.
void AfxDumpStack(unsigned long) Prototipo di funzione chiamato.
+ 181 bytes Offset in byte dall'indirizzo del prototipo di funzione (in questo caso , void AfxDumpStack(unsigned long)) all'indirizzo restituito (in questo caso, 00427D55).

AfxDumpStack è disponibile nelle versioni di debug e non diebug delle librerie MFC; Tuttavia, la funzione viene sempre collegata in modo statico, anche quando il file eseguibile usa MFC in una DLL condivisa. Nelle implementazioni della libreria condivisa, la funzione si trova in MFCS42. Libreria LIB (e le relative varianti).

Per usare correttamente questa funzione:

  • Il file IMAGEHLP.DLL deve trovarsi nel percorso. Se questa DLL non è disponibile, la funzione visualizzerà un messaggio di errore. Per informazioni sul set di funzioni fornito da IMAGEHLP, vedere Raccolta guida immagini.

  • I moduli con frame nello stack devono includere informazioni di debug. Se non contengono informazioni di debug, la funzione genererà comunque un'analisi dello stack, ma la traccia sarà meno dettagliata.

Requisiti

Intestazione: afx.h

AfxEnableMemoryLeakDump

Abilita e disabilita il dump della perdita di memoria nel distruttore AFX_DEBUG_STATE.

BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);

Parametri

bDump
[in] TRUE indica che il dump della perdita di memoria è abilitato; FALSE indica che il dump della perdita di memoria è disabilitato.

Valore restituito

Il valore precedente per questo flag.

Osservazioni:

Quando un'applicazione scarica la libreria MFC, quest'ultima controlla se si sono verificate perdite di memoria. A questo punto, eventuali perdite di memoria vengono segnalate all'utente tramite la finestra Debug di Visual Studio.

Se l'applicazione carica un'altra libreria prima della libreria MFC, alcune allocazioni di memoria in tale libreria verranno segnalate erroneamente come perdite di memoria. Per effetto di queste segnalazioni errate, è possibile che l'applicazione venga chiusa lentamente a mano a mano che le perdite vengono segnalate dalla libreria MFC. In tal caso, usare AfxEnableMemoryLeakDump per disabilitare il dump delle perdite di memoria.

Nota

Se si usa questo metodo per disabilitare il dump delle perdite di memoria, nell'applicazione non si riceveranno i report delle perdite di memoria effettive. È consigliabile usare questo metodo solo se si è certi che il report contenga informazioni errate sulle perdite di memoria.

Requisiti

Intestazione: afx.h

AfxEnableMemoryTracking

Il rilevamento della memoria diagnostica è in genere abilitato nella versione debug di MFC.

BOOL AfxEnableMemoryTracking(BOOL bTrack);

Parametri

bTrack
L'impostazione di questo valore su TRUE attiva il rilevamento della memoria; FALSE lo disattiva.

Valore restituito

Impostazione precedente del flag di abilitazione del rilevamento.

Osservazioni:

Usare questa funzione per disabilitare il rilevamento nelle sezioni del codice che si sa stanno allocando correttamente i blocchi.

Per altre informazioni su AfxEnableMemoryTracking, vedere Debug di applicazioni MFC.

Nota

Questa funzione funziona solo nella versione Debug di MFC.

Esempio

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;
}

Requisiti

Intestazione: afx.h

AfxIsMemoryBlock

Verifica un indirizzo di memoria per assicurarsi che rappresenti un blocco di memoria attualmente attivo allocato dalla versione diagnostica di new.

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

Parametri

p
Punta al blocco di memoria da testare.

nBytes
Contiene la lunghezza del blocco di memoria in byte.

plRequestNumber
Punta a un long numero intero che verrà compilato con il numero di sequenza di allocazione del blocco di memoria oppure zero se non rappresenta un blocco di memoria attualmente attivo.

Valore restituito

Diverso da zero se il blocco di memoria è attualmente allocato e la lunghezza è corretta; in caso contrario, 0.

Osservazioni:

Controlla anche le dimensioni specificate rispetto alle dimensioni allocate originali. Se la funzione restituisce un valore diverso da zero, il numero di sequenza di allocazione viene restituito in plRequestNumber. Questo numero rappresenta l'ordine in cui il blocco è stato allocato rispetto a tutte le altre new allocazioni.

Esempio

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

Requisiti

Intestazione: afx.h

AfxIsValidAddress

Verifica qualsiasi indirizzo di memoria per assicurarsi che sia contenuto interamente all'interno dello spazio di memoria del programma.

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

Parametri

Lp
Punta all'indirizzo di memoria da testare.

nBytes
Contiene il numero di byte di memoria da testare.

bReadWrite
Specifica se la memoria è sia per la lettura che per la scrittura (TRUE) o solo per la lettura (FALSE).

Valore restituito

Nelle compilazioni di debug, diverso da zero se il blocco di memoria specificato è contenuto interamente all'interno dello spazio di memoria del programma; in caso contrario, 0.

Nelle compilazioni non di debug, diverso da zero se lp non è NULL; in caso contrario, 0.

Osservazioni:

L'indirizzo non è limitato ai blocchi allocati da new.

Esempio

// 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));

Requisiti

Intestazione: afx.h

AfxIsValidString

Utilizzare questa funzione per determinare se un puntatore a una stringa è valido.

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

Parametri

lpsz
Puntatore da testare.

nLength
Specifica la lunghezza della stringa da testare, in byte. Il valore -1 indica che la stringa verrà terminata con null.

Valore restituito

Nelle compilazioni di debug, diverso da zero se il puntatore specificato punta a una stringa delle dimensioni specificate; in caso contrario, 0.

Nelle compilazioni non di debug, diverso da zero se lpsz non è NULL; in caso contrario, 0.

Esempio

// 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));

Requisiti

Intestazione: afx.h

AfxSetAllocHook

Imposta un hook che consente di chiamare la funzione specificata prima che ogni blocco di memoria venga allocato.

AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);

Parametri

pfnAllocHook
Specifica il nome della funzione da chiamare. Vedere le osservazioni per il prototipo di una funzione di allocazione.

Valore restituito

Diverso da zero se si vuole consentire l'allocazione; in caso contrario, 0.

Osservazioni:

L'allocatore di debug della memoria di Microsoft Foundation Class Library può chiamare una funzione hook definita dall'utente per consentire all'utente di monitorare un'allocazione di memoria e di controllare se l'allocazione è consentita. Le funzioni hook di allocazione vengono prototipi come indicato di seguito:

BOOL AFXAPI AllocHook( size_t nSize, BOOLbObject , LONG ); lRequestNumber

nSize
Dimensioni dell'allocazione di memoria proposta.

bObject
TRUE se l'allocazione è per un CObjectoggetto derivato da ; in caso contrario, FALSE.

lRequestNumber
Numero di sequenza dell'allocazione della memoria.

Si noti che la convenzione di chiamata AFXAPI implica che il chiamato deve rimuovere i parametri dallo stack.

Requisiti

Intestazione: afx.h

AfxDoForAllClasses

Chiama la funzione di iterazione specificata per tutte le classi derivate da serializzabili CObjectnello spazio di memoria dell'applicazione.

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

Parametri

pfn
Punta a una funzione di iterazione da chiamare per ogni classe. Gli argomenti della funzione sono un puntatore a un CRuntimeClass oggetto e un puntatore void a dati aggiuntivi forniti dal chiamante alla funzione.

pContext
Punta a dati facoltativi che il chiamante può fornire alla funzione di iterazione. Questo puntatore può essere NULL.

Osservazioni:

Le classi derivate da serializzabili CObjectsono classi derivate tramite la macro DECLARE_SERIAL. Il puntatore passato a AfxDoForAllClasses in pContext viene passato alla funzione di iterazione specificata ogni volta che viene chiamato.

Nota

Questa funzione funziona solo nella versione Debug di MFC.

Esempio

#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

Requisiti

Intestazione: afx.h

AfxDoForAllObjects

Esegue la funzione di iterazione specificata per tutti gli oggetti derivati da CObject allocati con new.

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

Parametri

pfn
Punta a una funzione di iterazione da eseguire per ogni oggetto. Gli argomenti della funzione sono un puntatore a un CObject e un puntatore void a dati aggiuntivi forniti dal chiamante alla funzione.

pContext
Punta a dati facoltativi che il chiamante può fornire alla funzione di iterazione. Questo puntatore può essere NULL.

Osservazioni:

Gli oggetti stack, globali o incorporati non vengono enumerati. Il puntatore passato a AfxDoForAllObjects in pContext viene passato alla funzione di iterazione specificata ogni volta che viene chiamato.

Nota

Questa funzione funziona solo nella versione Debug di MFC.

Esempio

#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

Vedi anche

Macro e globali
CObject::D ump