Speicherverwaltung und Debugheap
Aktualisiert: November 2007
Dieses Thema gilt für folgende Anwendungsbereiche:
Edition |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Express |
Nur "Systemeigen" |
|||
Standard |
Nur "Systemeigen" |
|||
Pro und Team |
Nur "Systemeigen" |
Tabellenlegende:
Vorhanden |
|
Nicht vorhanden |
|
Befehl oder Befehle, die standardmäßig ausgeblendet sind. |
Zwei der geläufigsten und hartnäckigsten Probleme, denen sich Programmierer immer wieder gegenüber sehen, ist das Überschreiben eines reservierten Pufferendes und Speicherverluste (wobei die Freigabe der nicht mehr benötigten Reservierung fehlschlägt). Der Debugheap stellt leistungsfähige Tools bereit, die derartige Speicherreservierungsprobleme beheben helfen.
Debugversionen von Heapreservierungsfunktionen
Durch die Debugversionen der Heapfunktionen wird die Standard- oder Basisversion aufgerufen, die in Releasebuilds verwendet wird. Wenn Sie einen Speicherblock anfordern, reserviert der Debugheap-Manager auf dem Basisheap einen Speicherblock, der geringfügig größer als der angeforderte ist, und gibt einen Zeiger auf den jeweiligen Bereich des Blocks zurück. Angenommen, die Anwendung enthält den malloc( 10 )-Aufruf. In einem Releasebuild wird von malloc die Reservierungsroutine für den Basisheap aufgerufen und eine Reservierung von 10 Bytes angefordert. In einem Debugbuild wird von malloc jedoch _malloc_dbg aufgerufen. Dieser ruft anschließend die Reservierungsroutine für den Basisheap auf und fordert eine Reservierung von 10 Bytes sowie etwa 36 Bytes an zusätzlichem Arbeitsspeicher an. Alle resultierenden Speicherblöcke im Debugheap werden über eine einzelne verknüpfte Liste verbunden und sind nach ihrem Reservierungszeitpunkt angeordnet.
Der durch die Debugheaproutinen reservierte Zusatzspeicher wird wie folgt verwendet: für Verwaltungsinformationen, für Zeiger, die die Debugspeicherblöcke verknüpfen, und für kleine Puffer auf beiden Seiten der Daten, um Überschreibungen des reservierten Bereichs abzufangen.
Derzeit ist die zum Speichern der Debugheap-Verwaltungsinformationen verwendete Blockheaderstruktur wie folgt in der Headerdatei DBGINT.H deklariert:
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];
*/
Die NoMansLand-Puffer auf beiden Seiten des Benutzerdatenbereichs belegen derzeit je 4 Bytes. Sie enthalten einen definierten Bytewert, mit dessen Hilfe die Debugheaproutinen sicherstellen, dass die Grenzen des reservierten Benutzerspeicherblocks nicht überschrieben wurden. Der Debugheap schreibt zusätzlich einen definierten Wert in neue Speicherblöcke. Wenn Sie freigegebene Blöcke, wie nachstehend beschrieben, in der verknüpften Heapliste belassen möchten, erhalten diese ebenfalls einen definierten Wert. Derzeit werden die folgenden Bytewerte verwendet:
NoMansLand (0xFD)
Die "NoMansLand"-Puffer auf beiden Seiten des von der Anwendung verwendeten Speichers enthalten derzeit den Wert 0xFD.Freigegebene Blöcke (0xDD)
Die freigegebenen Blöcke, die in der verknüpften Heapliste unbenutzt bleiben, wenn das _CRTDBG_DELAY_FREE_MEM_DF-Flag festgelegt ist, enthalten derzeit den Wert 0xDD.Neue Objekte (0xCD)
Neue Objekte werden bei der Reservierung mit 0xCD beschrieben.