La administración de memoria y el montón de depuración

Actualización: noviembre 2007

Este tema es aplicable a:

Edición

Visual Basic

C#

C++

Web Developer

Express

Sólo para código nativo

Standard

Sólo para código nativo

Pro y Team

Sólo para código nativo

Leyenda de la tabla:

Se aplica

No procede

Comando o comandos ocultos de forma predeterminada.

Dos de los problemas más comunes y difíciles de tratar con los que se encuentran los programadores son la sobrescritura al final de un búfer asignado y las pérdidas de memoria (incapacidad de liberar asignaciones de memoria que ya no se necesitan). El montón de depuración proporciona herramientas eficaces para solucionar este tipo de problemas de asignación de memoria.

Versiones de depuración de las funciones del montón

Las versiones de depuración de las funciones del montón llaman a las versiones base o estándar utilizadas en las versiones de lanzamiento. Cuando se solicita un bloque de memoria, el administrador del montón de depuración asigna en el montón base un bloque de memoria ligeramente mayor que el solicitado y devuelve un puntero a la parte solicitada. Por ejemplo, suponga que la aplicación contiene la llamada: malloc( 10 ). En una versión de lanzamiento, malloc llamaría a la rutina base de asignación en el montón y solicitaría una asignación de memoria de 10 bytes. Sin embargo, en una versión de depuración, malloc llamaría a _malloc_dbg, que, a su vez, llamaría a la rutina base de asignación en el montón y solicitaría una asignación de 10 bytes más unos 36 bytes de memoria adicionales. Todos los bloques de memoria del montón de depuración se encuentran conectados en una lista simplemente vinculada, ordenados según el momento en que fueron asignados.

La memoria adicional asignada por las rutinas del montón de depuración se utiliza para contabilizar información, para punteros que vinculan bloques de memoria de depuración entre sí y para pequeños búferes a cada lado de los datos que permiten capturar sobrescrituras en la región asignada.

Actualmente, la estructura de encabezado de bloque que se utiliza para almacenar esa información de contabilidad del montón se declara en el archivo de encabezado DBGINT.H del siguiente modo:

typedef struct _CrtMemBlockHeader
{
// Pointer to the block allocated just before this one:
    struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
    struct _CrtMemBlockHeader *pBlockHeaderPrev;
    char *szFileName;    // File name
    int nLine;           // Line number
    size_t nDataSize;    // Size of user block
    int nBlockUse;       // Type of block
    long lRequest;       // Allocation number
// Buffer just before (lower than) the user's memory:
    unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;

/* In an actual memory block in the debug heap,
 * this structure is followed by:
 *   unsigned char data[nDataSize];
 *   unsigned char anotherGap[nNoMansLandSize];
 */

Los búferes NoMansLand situados a cada lado del área de datos de usuario del bloque ocupan actualmente 4 bytes y se rellenan con un valor de byte conocido utilizado por las rutinas del montón de depuración para comprobar que los límites del bloque de memoria del usuario no se han sobrescrito. El montón de depuración también rellena nuevos bloques de memoria con un valor conocido. Si elige mantener los bloques liberados en la lista vinculada del montón como se explica más adelante, estos bloques liberados se rellenan también con un valor conocido. Comúnmente, los valores de byte utilizados son:

  • NoMansLand (0xFD)
    Los búferes "NoMansLand", situados a cada lado de la memoria utilizada por una aplicación, se rellenan con 0xFD.

  • Bloques liberados (0xDD)
    Los bloques liberados que permanecían sin utilizar en la lista vinculada del montón de depuración, cuando se establece el marcador _CRTDBG_DELAY_FREE_MEM_DF, se rellenan con 0xDD.

  • Nuevos objetos (0xCD)
    Los objetos nuevos se rellenan con 0xCD al asignarse.

Vea también

Otros recursos

El montón de depuración de CRT