Esta documentación está archivada y no tiene mantenimiento.

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

Este tema es aplicable a:

Edición de Visual Studio

Visual Basic

C#

C++

J#

Express

No

No

Código nativo

No

Standard

No

No

Código nativo

No

Pro/Team

No

No

Código nativo

No

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 enlazada, 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 enlazada 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 se mantiene sin utilizar en la lista enlazada del montón de depuración cuando se utiliza el indicador _CRTDBG_DELAY_FREE_MEM_DF se rellenan con 0xDD.

Nuevos objetos (0xCD)

Los objetos nuevos se rellenan con 0xCD al asignarse.

Vea también

Mostrar: