Servicios de diagnóstico

La biblioteca MFC (Microsoft Foundation Class) ofrece muchos servicios de diagnóstico que facilitan la depuración de los programas con mayor facilidad. Estos servicios de diagnóstico incluyen macros y funciones globales que le permiten realizar un seguimiento de las asignaciones de memoria de su programa, volcar el contenido de los objetos en tiempo de ejecución e imprimir mensajes de depuración en tiempo de ejecución. Las macros y funciones globales para servicios de diagnóstico se agrupan en las siguientes categorías:

  • Macros de diagnóstico generales

  • Funciones y variables de diagnóstico general

  • Funciones de diagnóstico de objetos

Estas macros y funciones están disponibles para todas las clases derivadas de CObject en las versiones de lanzamiento y depuración de MFC. Pero todas excepto DEBUG_NEW y VERIFY no hacen nada en la versión de lanzamiento.

En la biblioteca de depuración, todos los bloques de memoria asignados están entre corchetes con una serie de "bytes de protección". Si una escritura de memoria errante afecta a estos bytes, las rutinas de diagnóstico pueden notificar un problema. Si incluye la línea:

#define new DEBUG_NEW

en el archivo de implementación, todas las llamadas a new almacenarán el nombre de archivo y el número de línea en el que se realizó la asignación de memoria. La función CMemoryState::DumpAllObjectsSince mostrará esta información adicional, lo que le permitirá identificar fugas de memoria. Consulte también la clase CDumpContext para información adicional sobre el resultado de diagnóstico.

Además, la biblioteca de tiempo de ejecución de C también admite un conjunto de funciones de diagnóstico que puede usar para depurar sus aplicaciones. Para más información, vea Rutinas de depuración en la Referencia de la biblioteca en tiempo de ejecución.

Macros de diagnóstico generales de MFC

Nombre Descripción
ASSERT Imprime un mensaje y luego anula el programa si la expresión especificada se evalúa como FALSE en la versión de depuración de la biblioteca.
ASSERT_KINDOF Prueba que un objeto es un objeto de la clase especificada o de una clase derivada de la clase especificada.
ASSERT_VALID Prueba la validez interna de un objeto llamando a su función de miembro AssertValid ; normalmente invalidada desde CObject.
DEBUG_NEW Ofrece un nombre de archivo y un número de línea para todas las asignaciones de objetos en modo de depuración para ayudar a encontrar fugas de memoria.
DEBUG_ONLY Similar a ASSERT pero no prueba el valor de la expresión; útil para código que se debe ejecutar solo en modo de depuración.
ENSURE y ENSURE_VALID Úselos para validar la corrección de los datos.
THIS_FILE Se expande al nombre del archivo que se está compilando.
TRACE Ofrece capacidad similar a printfen la versión de depuración de la biblioteca.
VERIFY Similar a ASSERT pero evalúa la expresión en la versión de lanzamiento de la biblioteca, así como en la versión de depuración.

Funciones y variables de diagnóstico general de MFC

Nombre Descripción
afxDump Variable global que envía información de CDumpContext a la ventana de salida del depurador o al terminal de depuración.
afxMemDF Variable global que controla el comportamiento del asignador de memoria de depuración.
AfxCheckError Variable global que se usa para probar el SCODE pasado para ver si es un error y, si es así, genera el error correspondiente.
AfxCheckMemory Comprueba la integridad de toda la memoria asignada actualmente.
AfxDebugBreak Provoca una interrupción en la ejecución.
AfxDump Si se llama mientras se encuentra en el depurador, vuelca el estado de un objeto durante la depuración.
AfxDump Función interna que realiza un volcado de memoria del estado de un objeto durante la depuración.
AfxDumpStack Genera una imagen de la pila actual. Esta función siempre está vinculada estáticamente.
AfxEnableMemoryLeakDump Habilita el volcado de fuga de memoria.
AfxEnableMemoryTracking Activa y desactiva el seguimiento de la memoria.
AfxIsMemoryBlock Comprueba que se ha asignado correctamente un bloque de memoria.
AfxIsValidAddress Comprueba que un intervalo de direcciones de memoria se encuentra dentro de los límites del programa.
AfxIsValidString Determina si un puntero a una cadena es válido.
AfxSetAllocHook Permite la llamada de una función en cada asignación de memoria.

Funciones de diagnóstico de objetos de MFC

Nombre Descripción
AfxDoForAllClasses Realiza una función especificada en todas las clases derivadas por CObjectque admiten la comprobación de tipos en tiempo de ejecución.
AfxDoForAllObjects Realiza una función especificada en todos los objetos derivados por CObjectasignados con new.

Macros de compilación MFC

Nombre Descripción
_AFX_SECURE_NO_WARNINGS Suprime las advertencias del compilador por el uso de funciones MFC en desuso.

_AFX_SECURE_NO_WARNINGS

Suprime las advertencias del compilador por el uso de funciones MFC en desuso.

Sintaxis

_AFX_SECURE_NO_WARNINGS

Ejemplo

Este ejemplo de código produce una advertencia del compilador si _AFX_SECURE_NO_WARNINGS no está definido.

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

Llame a esta función para provocar una interrupción (en la ubicación de la llamada a AfxDebugBreak) en la ejecución de la versión de depuración de la aplicación MFC.

Sintaxis

void AfxDebugBreak( );

Comentarios

AfxDebugBreak no tiene ningún efecto en las versiones de lanzamiento de una aplicación MFC y debe quitarse. Esta función solo debe usarse en aplicaciones MFC. Use la versión de API Win32, DebugBreak, para provocar una interrupción en las aplicaciones que no son MFC.

Requisitos

Encabezado: afxver_.h

ASSERT

Evalúa su argumento.

ASSERT(booleanExpression)

Parámetros

booleanExpression
Especifica una expresión (incluidos los valores de puntero) que se evalúa como distinto de cero o 0.

Comentarios

Si el resultado es 0, la macro imprime un mensaje de diagnóstico y anula el programa. Si la condición es distinta de cero, no hace nada.

El mensaje de diagnóstico tiene la forma

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

donde name es el nombre del archivo de código fuente y num es el número de línea de la aserción que produjo un error en el archivo de código fuente.

En la versión de lanzamiento de MFC, ASSERT no evalúa la expresión y, por tanto, no interrumpirá el programa. Si la expresión se debe evaluar independientemente del entorno, use la macro VERIFY en lugar de ASSERT.

Nota:

Esta función solo está disponible en la versión de depuración de MFC.

Ejemplo

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

Requisitos

Encabezado: afx.h

ASSERT_KINDOF

Esta macro afirma que el objeto al que se apunta es un objeto de la clase especificada o es un objeto de una clase derivada de la clase especificada.

ASSERT_KINDOF(classname, pobject)

Parámetros

classname
Nombre de una clase derivada de CObject.

pobject
Puntero a un objeto de clase.

Comentarios

El pobject debe ser un puntero a un objeto y puede ser const. El objeto al que apunta y la clase deben admitir información de clase en tiempo de ejecución de CObject. Por ejemplo, para asegurarse de que pDocument es un puntero a un objeto de la clase CMyDoc, o cualquiera de sus derivados, puede programar lo siguiente:

ASSERT_KINDOF(CMyDoc, pDocument);

El uso del macro ASSERT_KINDOF es exactamente igual que programar lo siguiente:

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

Esta función solo funciona para las clases declaradas con la macro [DECLARE_DYNAMIC](run-time-object-model-services.md#declare_dynamic o DECLARE_SERIAL.

Nota:

Esta función solo está disponible en la versión de depuración de MFC.

Requisitos

Encabezado: afx.h

ASSERT_VALID

Úselo para probar sus suposiciones sobre la validez del estado interno de un objeto.

ASSERT_VALID(pObject)

Parámetros

pObject
Especifica un objeto de una clase derivada de CObject que tiene una versión reemplazada de la función miembro AssertValid.

Comentarios

ASSERT_VALID llama a la función miembro AssertValid del objeto pasado como argumento.

En la versión de lanzamiento de MFC, ASSERT_VALID no hace nada. En la versión de depuración, valida el puntero, comprueba NULL y llama a las funciones miembro AssertValid del objeto. Si se produce un error en cualquiera de estas pruebas, se muestra un mensaje de alerta de la misma forma que ASSERT.

Nota:

Esta función solo está disponible en la versión de depuración de MFC.

Para más información y ejemplos, vea Técnicas de depuración de MFC.

Ejemplo

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

Requisitos

Encabezado: afx.h

DEBUG_NEW

Ayuda a encontrar fugas de memoria.

#define  new DEBUG_NEW

Comentarios

Puede usar DEBUG_NEW en todas las partes del programa que normalmente usarían el operador new para asignar almacenamiento del montón.

En modo de depuración (cuando se define el símbolo _DEBUG), DEBUG_NEW realiza un seguimiento del nombre de archivo y el número de línea de cada objeto que asigna. Después, cuando se usa la función miembro CMemoryState::DumpAllObjectsSince, cada objeto asignado con DEBUG_NEW se muestra con el nombre de archivo y el número de línea donde se asignó.

Para usar DEBUG_NEW, inserte la siguiente directiva en los archivos de origen:

#define new DEBUG_NEW

Una vez haya insertado esta directiva, el preprocesador insertará DEBUG_NEW dondequiera que use new, y MFC hará el resto. Al compilar una versión de lanzamiento del programa, DEBUG_NEW se resuelve en una operación new sencilla y no se genera la información de nombre de archivo y número de línea.

Nota:

En versiones anteriores de MFC (4.1 y versiones anteriores) era necesario colocar la instrucción #define después de todas las instrucciones que llamaban a las macros IMPLEMENT_DYNCREATE o IMPLEMENT_SERIAL. Ya no es necesario.

Requisitos

Encabezado: afx.h

DEBUG_ONLY

En el modo de depuración (cuando se define el símbolo _DEBUG), DEBUG_ONLY evalúa su argumento.

DEBUG_ONLY(expression)

Comentarios

En una compilación de versión, DEBUG_ONLY no evalúa su argumento. Esto resulta útil cuando tiene código que solo se debe ejecutar en compilaciones de depuración.

La macro DEBUG_ONLY es equivalente a rodear expression con #ifdef _DEBUG y #endif.

Ejemplo

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

Requisitos

Encabezado: afx.h

ENSURE y ENSURE_VALID

Úselos para validar la corrección de los datos.

Sintaxis

ENSURE(  booleanExpression )
ENSURE_VALID( booleanExpression  )

Parámetros

booleanExpression
Especifica una expresión booleana que se va a probar.

Comentarios

El propósito de estas macros es mejorar la validación de los parámetros. Las macros impiden el procesamiento adicional de parámetros incorrectos en el código. A diferencia de las macros ASSERT, las macros ENSURE inician una excepción además de generar una aserción.

Las macros se comportan de dos maneras, según la configuración del proyecto. Las macros llaman a ASSERT y, después, inician una excepción si se produce un error en la aserción. Por lo tanto, en las configuraciones de depuración (es decir, donde se define _DEBUG), las macros generan una aserción y una excepción, mientras que en las configuraciones de versión, las macros generan solo la excepción (ASSERT no evalúa la expresión en las configuraciones de versión).

La macro ENSURE_ARG actúa como la macro ENSURE.

ENSURE_VALID llama a la macro ASSERT_VALID (que solo tiene efecto en las compilaciones de depuración). Además, ENSURE_VALID produce una excepción si el puntero es NULL. La prueba NULL se realiza en las configuraciones de depuración y de versión.

Si se produce un error en cualquiera de estas pruebas, se muestra un mensaje de alerta de la misma forma que ASSERT. La macro produce una excepción de argumento no válido si es necesario.

Requisitos

Encabezado: afx.h

THIS_FILE

Se expande al nombre del archivo que se está compilando.

Sintaxis

THIS_FILE

Comentarios

Las macros ASSERT y VERIFY usan la información. El Asistente para aplicaciones y los asistentes para código colocan la macro en los archivos de código fuente que crean.

Ejemplo

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

Requisitos

Encabezado: afx.h

TRACE

Envía la cadena especificada al depurador de la aplicación actual.

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

Comentarios

Vea ATLTRACE2 para una descripción de TRACE. TRACE y ATLTRACE2 tienen el mismo comportamiento.

En la versión de depuración de MFC, esta macro envía la cadena especificada al depurador de la aplicación actual. En una compilación de versión, esta macro no se compila en nada (no se genera ningún código).

Para más información, vea Técnicas de depuración de MFC.

Requisitos

Encabezado: afx.h

VERIFY

En la versión de depuración de MFC, evalúa su argumento.

VERIFY(booleanExpression)

Parámetros

booleanExpression
Especifica una expresión (incluidos los valores de puntero) que se evalúa como distinto de cero o 0.

Comentarios

Si el resultado es 0, la macro imprime un mensaje de diagnóstico y detiene el programa. Si la condición es distinta de cero, no hace nada.

El mensaje de diagnóstico tiene la forma

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

donde name es el nombre del archivo de código fuente y num es el número de línea de la aserción que produjo un error en el archivo de código fuente.

En la versión de lanzamiento de MFC, VERIFY evalúa la expresión, pero no imprime ni interrumpe el programa. Por ejemplo, si la expresión es una llamada de función, se realizará la llamada.

Ejemplo

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

Requisitos

Encabezado: afx.h

afxDump (CDumpContext en MFC)

Proporciona la funcionalidad básica de volcado de memoria de objetos en la aplicación.

CDumpContext  afxDump;

Comentarios

afxDump es un objeto CDumpContext predefinido que permite enviar información CDumpContext a la ventana de salida del depurador o a un terminal de depuración. Normalmente, se proporciona afxDump como parámetro para CObject::Dump.

En Windows NT y todas las versiones de Windows, la salida afxDump se envía a la ventana Output-Debug (Depuración de salida) de Visual C++ al depurar la aplicación.

Esta variable solo se define en la versión de depuración de MFC. Para más información sobre afxDump, vea Técnicas de depuración de MFC.

Ejemplo

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

Requisitos

Encabezado: afx.h

AfxDump (interno)

Función interna que usa MFC para realizar un volcado de memoria del estado de un objeto durante la depuración.

Sintaxis

void AfxDump(const CObject* pOb);

Parámetros

pOb
Puntero a un objeto de una clase derivada de CObject.

Comentarios

AfxDump llama a la función miembro Dump de un objeto y envía la información a la ubicación especificada por la variable afxDump. AfxDump solo está disponible en la versión de depuración de MFC.

El código de programa no debe llamar a AfxDump, sino que debe llamar a la función miembro Dump del objeto adecuado.

Requisitos

Encabezado: afx.h

afxMemDF

Esta variable es accesible desde un depurador o el programa y permite optimizar los diagnósticos de asignación.

int  afxMemDF;

Comentarios

afxMemDF puede tener los siguientes valores según lo especificado por la enumeración afxMemDF:

  • allocMemDF Activa el asignador de depuración (configuración predeterminada en la biblioteca de depuración).

  • delayFreeMemDF Retrasa la liberación de memoria. Aunque el programa libera un bloque de memoria, el asignador no devuelve esa memoria al sistema operativo subyacente. Esto colocará el esfuerzo máximo de memoria en el programa.

  • checkAlwaysMemDF Llama a AfxCheckMemory cada vez que se asigna o libera memoria. Esto ralentizará significativamente las asignaciones y desasignaciones de memoria.

Ejemplo

afxMemDF = allocMemDF | checkAlwaysMemDF;

Requisitos

Encabezado: afx.h

AfxCheckError

Esta función prueba el SCODE que ha pasado para ver si se trata de un error.

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

Comentarios

Si se trata de un error, la función produce una excepción. Si el SCODE pasado es E_OUTOFMEMORY, la función inicia una excepción CMemoryException mediante una llamada a AfxThrowMemoryException. De lo contrario, la función produce una excepción COleException mediante una llamada a AfxThrowOleException.

Esta función se puede usar para comprobar los valores devueltos de las llamadas a funciones OLE en la aplicación. Al probar el valor devuelto con esta función en la aplicación, puede reaccionar correctamente a las condiciones de error con una cantidad mínima de código.

Nota:

Esta función tiene el mismo efecto en las compilaciones de depuración y no depuración.

Ejemplo

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

oddWMP.AttachDispatch(pWMPDispatch, TRUE);

Requisitos

Encabezado: afx.h

AfxCheckMemory

Esta función valida el grupo de memoria libre e imprime los mensajes de error según sea necesario.

BOOL  AfxCheckMemory();

Valor devuelto

Distinto de cero si no hay errores de memoria; de lo contrario, 0.

Comentarios

Si la función no detecta daños en la memoria, no imprime nada.

Se comprueban todos los bloques de memoria asignados actualmente en el montón, incluidos los asignados por new, pero no los asignados por llamadas directas a asignadores de memoria subyacentes, como la función malloc o la función GlobalAlloc de Windows. Si se encuentra algún bloque dañado, se imprime un mensaje en la salida del depurador.

Si incluye la línea

#define new DEBUG_NEW

en un módulo de programa, las llamadas posteriores a AfxCheckMemory muestran el nombre de archivo y el número de línea donde se asignó la memoria.

Nota:

Si el módulo contiene una o varias implementaciones de clases que se pueden serializar, debe colocar la línea #define después de la última llamada de macro de IMPLEMENT_SERIAL.

Esta función solo funciona en la versión de depuración de MFC.

Ejemplo

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

Requisitos

Encabezado: afx.h

AfxDump (MFC)

Llame a esta función mientras está en el depurador para realizar un volcado de memoria en el estado de un objeto durante la depuración.

void AfxDump(const CObject* pOb);

Parámetros

pOb
Puntero a un objeto de una clase derivada de CObject.

Comentarios

AfxDump llama a la función miembro Dump de un objeto y envía la información a la ubicación especificada por la variable afxDump. AfxDump solo está disponible en la versión de depuración de MFC.

El código de programa no debe llamar a AfxDump, sino que debe llamar a la función miembro Dump del objeto adecuado.

Requisitos

Encabezado: afx.h

AfxDumpStack

Esta función global se puede usar para generar una imagen de la pila actual.

void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT);

Parámetros

dwTarget
Indica el destino de la salida del volcado de memoria. Los valores posibles, que se pueden combinar mediante el operador OR bit a bit (|), son los siguientes:

  • AFX_STACK_DUMP_TARGET_TRACE Envía la salida mediante la macro TRACE. La macro TRACE solo genera resultados en compilaciones de depuración; no genera ninguna salida en las compilaciones de versión. Además, TRACE se puede redirigir a otros destinos además del depurador.

  • AFX_STACK_DUMP_TARGET_DEFAULT Envía la salida de volcado de memoria al destino predeterminado. Para una compilación de depuración, la salida va a la macro TRACE. En una compilación de versión, la salida va al Portapapeles.

  • AFX_STACK_DUMP_TARGET_CLIPBOARD Envía la salida solo al Portapapeles. Los datos se colocan en el Portapapeles como texto sin formato con el formato de Portapapeles CF_TEXT.

  • AFX_STACK_DUMP_TARGET_BOTH Envía la salida al Portapapeles y a la macro TRACE de forma simultánea.

  • AFX_STACK_DUMP_TARGET_ODS Envía la salida directamente al depurador mediante la función OutputDebugString() de Win32. Esta opción generará la salida del depurador tanto en las compilaciones de depuración como en las de versión cuando se adjunta un depurador al proceso. AFX_STACK_DUMP_TARGET_ODS siempre llega al depurador (si está asociado) y no se puede redirigir.

Comentarios

En el ejemplo siguiente se refleja una sola línea de la salida generada al llamar a AfxDumpStack desde un controlador de botón en una aplicación MFC de diálogo:

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

Cada línea de la salida anterior indica la dirección de la última llamada de función, el nombre de la ruta de acceso completa del módulo que contiene la llamada de función y el prototipo de función llamado. Si la llamada de función en la pila no se realiza en la dirección exacta de la función, se muestra un desplazamiento de bytes.

Por ejemplo, en la tabla siguiente se describe la primera línea de la salida anterior:

Salida Descripción
00427D55: Dirección de retorno de la última llamada de función.
DUMP2\DEBUG\DUMP2.EXE! Nombre de ruta de acceso completa del módulo que contiene la llamada de función.
void AfxDumpStack(unsigned long) Prototipo de función llamado.
+ 181 bytes Desplazamiento en bytes desde la dirección del prototipo de función (en este caso, void AfxDumpStack(unsigned long)) a la dirección de devolución (en este caso, 00427D55).

AfxDumpStack está disponible en las versiones de depuración y no depuración de las bibliotecas MFC; pero la función siempre está vinculada de forma estática, incluso cuando el archivo ejecutable usa MFC en una DLL compartida. En las implementaciones de biblioteca compartida, la función se encuentra en MFCS42. Biblioteca LIB (y sus variantes).

Para usar esta función correctamente tenga en cuenta lo siguiente:

  • El archivo IMAGEHLP.DLL debe estar en la ruta de acceso. Si no tiene esta DLL, la función mostrará un mensaje de error. Consulte Biblioteca de ayuda de imágenes para obtener información sobre el conjunto de funciones proporcionado por IMAGEHLP.

  • Los módulos que tienen marcos en la pila deben incluir información de depuración. Si no contienen información de depuración, la función seguirá generando un seguimiento de pila, pero será menos detallado.

Requisitos

Encabezado: afx.h

AfxEnableMemoryLeakDump

Habilita y deshabilita el volcado de pérdida de memoria en el destructor AFX_DEBUG_STATE.

BOOL AFXAPI AfxEnableMemoryLeakDump(BOOL bDump);

Parámetros

bDump
[in] TRUE indica que el volcado de fuga de memoria está habilitado, mientras que FALSE indica que está deshabilitado.

Valor devuelto

Valor anterior de esta marca.

Comentarios

Cuando una aplicación descarga la biblioteca MFC, esta comprueba si hay pérdidas de memoria. En este punto, las fugas de memoria se notifican al usuario mediante la ventana Depuración de Visual Studio.

Si la aplicación carga otra biblioteca antes que la biblioteca MFC, algunas asignaciones de memoria de la biblioteca se notificarán incorrectamente como pérdidas de memoria. Las pérdidas de memoria falsas pueden hacer que la aplicación se cierre lentamente, ya que la biblioteca MFC las estará notificando. En este caso, use AfxEnableMemoryLeakDump para deshabilitar el volcado de pérdida de memoria.

Nota:

Si usa este método para desactivar el volcado de pérdida de memoria, no recibirá ningún informe de pérdidas de memoria válidas en la aplicación. Solo debe usar este método si está seguro de que el informe de pérdida de memoria contiene pérdidas de memoria falsas.

Requisitos

Encabezado: afx.h

AfxEnableMemoryTracking

El seguimiento de la memoria de diagnóstico suele estar habilitado en la versión de depuración de MFC.

BOOL AfxEnableMemoryTracking(BOOL bTrack);

Parámetros

bTrack
Al establecer este valor en TRUE, se activa el seguimiento de memoria; FALSE lo desactiva.

Valor devuelto

La configuración anterior de la marca de habilitación de seguimiento.

Comentarios

Use esta función para deshabilitar el seguimiento en secciones del código que sabe que están asignando bloques de forma correcta.

Para más información sobre AfxEnableMemoryTracking, vea Técnicas de depuración de MFC.

Nota:

Esta función solo funciona en la versión de depuración de MFC.

Ejemplo

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

Requisitos

Encabezado: afx.h

AfxIsMemoryBlock

Prueba una dirección de memoria para asegurarse de que representa un bloque de memoria actualmente activo asignado por la versión de diagnóstico de new.

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

Parámetros

p
Apunta al bloque de memoria que se va a probar.

nBytes
Contiene la longitud del bloque de memoria en bytes.

plRequestNumber
Apunta a un entero long que se rellenará con el número de secuencia de asignación del bloque de memoria o cero si no representa un bloque de memoria activo actualmente.

Valor devuelto

Distinto de cero si el bloque de memoria está asignado actualmente y la longitud es correcta; de lo contrario, 0.

Comentarios

También comprueba el tamaño especificado con respecto al tamaño asignado original. Si la función devuelve un valor distinto de cero, el número de secuencia de asignación se devuelve en plRequestNumber. Este número representa el orden en el que se asignó el bloque en relación con todas las demás asignaciones new.

Ejemplo

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

Requisitos

Encabezado: afx.h

AfxIsValidAddress

Comprueba cualquier dirección de memoria para asegurarse de que se encuentra completamente dentro del espacio de memoria del programa.

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

Parámetros

Lp
Apunta a la dirección de memoria que se va a probar.

nBytes
Contiene el número de bytes de memoria que se van a probar.

bReadWrite
Especifica si la memoria es para leer y escribir (TRUE) o solo leer (FALSE).

Valor devuelto

En las compilaciones de depuración, distinto de cero si el bloque de memoria especificado está contenido completamente dentro del espacio de memoria del programa; de lo contrario, 0.

En compilaciones que no son de depuración, distinto de cero si lp no es NULL; de lo contrario, 0.

Comentarios

La dirección no está restringida a los bloques asignados por new.

Ejemplo

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

Requisitos

Encabezado: afx.h

AfxIsValidString

Use esta función para determinar si un puntero a una cadena es válido.

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

Parámetros

lpsz
Puntero que se va a probar.

nLength
Especifica la longitud de la cadena que se va a probar, en bytes. Un valor de -1 indica que la cadena finalizará en null.

Valor devuelto

En las compilaciones de depuración, es distinto de cero si el puntero especificado apunta a una cadena del tamaño especificado; de lo contrario, 0.

En las compilaciones que no son de depuración, es distinto de cero si lpsz no es NULL; de lo contrario, 0.

Ejemplo

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

Requisitos

Encabezado: afx.h

AfxSetAllocHook

Establece un enlace que permite llamar a la función especificada antes de asignar cada bloque de memoria.

AFX_ALLOC_HOOK AfxSetAllocHook(AFX_ALLOC_HOOK pfnAllocHook);

Parámetros

pfnAllocHook
Especifica el nombre de la función que se va a llamar. Consulte los comentarios del prototipo de una función de asignación.

Valor devuelto

Distinto de cero si desea permitir la asignación; de lo contrario, 0.

Comentarios

El asignador de depuración de memoria de la biblioteca MFC (Microsoft Foundation Class) puede llamar a una función de enlace definida por el usuario para permitir al usuario supervisar una asignación de memoria y controlar si se permite la asignación. Las funciones de enlace de asignación se vuelven prototipos de la siguiente manera:

BOOL AFXAPI AllocHook( size_tnSize, BOOLbObject, LONGlRequestNumber);

nSize
Tamaño de la asignación de memoria propuesta.

bObject
TRUE si la asignación es para un objeto derivado de CObject; en caso contrario, FALSE.

lRequestNumber
Número de secuencia de la asignación de memoria.

Tenga en cuenta que la convención de llamada de AFXAPI implica que el destinatario debe quitar los parámetros de la pila.

Requisitos

Encabezado: afx.h

AfxDoForAllClasses

Llama a la función de iteración especificada para todas las clases derivadas de CObject que se pueden serializar en el espacio de memoria de la aplicación.

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

Parámetros

pfn
Apunta a una función de iteración a la que se llamará para cada clase. Los argumentos de función son un puntero a un objeto CRuntimeClass y un puntero void a datos adicionales que el autor de la llamada proporciona a la función.

pContext
Apunta a datos opcionales que el autor de la llamada puede proporcionar a la función de iteración. Este puntero puede ser NULL.

Comentarios

Las clases derivadas de CObject que se pueden serializar son clases derivadas mediante la macro DECLARE_SERIAL. El puntero que se pasa a AfxDoForAllClasses en pContext se pasa a la función de iteración especificada cada vez que se la llama.

Nota:

Esta función solo funciona en la versión de depuración de MFC.

Ejemplo

#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

Requisitos

Encabezado: afx.h

AfxDoForAllObjects

Ejecuta la función de iteración especificada para todos los objetos derivados de CObject que se han asignado con new.

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

Parámetros

pfn
Apunta a una función de iteración que se va a ejecutar para cada objeto. Los argumentos de función son un puntero a CObject y un puntero void a datos adicionales que el autor de la llamada proporciona a la función.

pContext
Apunta a datos opcionales que el autor de la llamada puede proporcionar a la función de iteración. Este puntero puede ser NULL.

Comentarios

Los objetos incrustados, globales o de pila no se enumeran. El puntero pasado a AfxDoForAllObjects en pContext se pasa a la función de iteración especificada cada vez que se la llama.

Nota:

Esta función solo funciona en la versión de depuración de MFC.

Ejemplo

#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

Consulte también

Macros y globales
CObject::Dump