Details zum CRT-DebugheapCRT Debug Heap Details

Dieses Thema umfasst eine detaillierte Erläuterung des CRT‑Debugheaps.This topic provides a detailed look at the CRT debug heap.

InhaltContents

Suchen von Pufferüberläufen mit DebugheapFind buffer overruns with debug heap

Blocktypen auf dem DebugheapTypes of blocks on the debug heap

Überprüfen auf Heapintegrität und SpeicherverlusteCheck for heap integrity and memory leaks

Konfigurieren des DebugheapsConfigure the debug heap

„new“, „delete“ und „_CLIENT_BLOCK“ im C++-Debugheapnew, delete, and _CLIENT_BLOCKs in the C++ debug heap

Berichtsfunktionen für den HeapzustandHeap State Reporting Functions

Nachverfolgen von HeapzuweisungsanforderungenTrack Heap Allocation Requests

Suchen von Pufferüberläufen mit DebugheapFind buffer overruns with debug heap

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 Belegung fehlschlägt).Two of the most common and intractable problems that programmers encounter are overwriting the end of an allocated buffer and memory leaks (failing to free allocations after they are no longer needed). Der Debugheap stellt leistungsfähige Tools bereit, die derartige Speicherbelegungsprobleme beheben helfen.The debug heap provides powerful tools to solve memory allocation problems of this kind.

Durch die Debugversionen der Heapfunktionen wird die Standard- oder Basisversion aufgerufen, die in Releasebuilds verwendet wird.The Debug versions of the heap functions call the standard or base versions used in Release builds. Wenn Sie einen Speicherblock anfordern, belegt 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.When you request a memory block, the debug heap manager allocates from the base heap a slightly larger block of memory than requested and returns a pointer to your portion of that block. Angenommen, die Anwendung enthält den malloc( 10 )-Aufruf.For example, suppose your application contains the call: malloc( 10 ). In einem Releasebuild würde malloc die Basis Heap-Zuordnungs Routine aufrufen, die eine Zuordnung von 10 Bytes anfordert.In a Release build, malloc would call the base heap allocation routine requesting an allocation of 10 bytes. In einem Debugbuild würde malloc jedoch _malloc_dbgaufrufen, das dann die Basis Heap-Zuordnungs Routine aufruft, die eine Zuordnung von 10 Bytes plus ungefähr 36 Bytes zusätzlichen Arbeitsspeichers anfordert.In a Debug build, however, malloc would call _malloc_dbg, which would then call the base heap allocation routine requesting an allocation of 10 bytes plus approximately 36 bytes of additional memory. Alle resultierenden Speicherblöcke im Debugheap werden über eine einzelne verknüpfte Liste verbunden und sind nach ihrem Reservierungszeitpunkt angeordnet.All the resulting memory blocks in the debug heap are connected in a single linked list, ordered according to when they were allocated.

Der durch die Debugheaproutinen belegte 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.The additional memory allocated by the debug heap routines is used for bookkeeping information, for pointers that link debug memory blocks together, and for small buffers on either side of your data to catch overwrites of the allocated region.

Derzeit ist die zum Speichern der Debugheap-Verwaltungsinformationen verwendete Blockheaderstruktur wie folgt in der Headerdatei DBGINT.H deklariert:Currently, the block header structure used to store the debug heap's bookkeeping information is declared as follows in the DBGINT.H header file:

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 belegten Benutzerspeicherblocks nicht überschrieben wurden.The NoMansLand buffers on either side of the user data area of the block are currently 4 bytes in size, and are filled with a known byte value used by the debug heap routines to verify that the limits of the user's memory block have not been overwritten. Der Debugheap schreibt zusätzlich einen definierten Wert in neue Speicherblöcke.The debug heap also fills new memory blocks with a known value. Wenn Sie freigegebene Blöcke, wie nachstehend beschrieben, in der verknüpften Heapliste belassen möchten, erhalten diese ebenfalls einen definierten Wert.If you elect to keep freed blocks in the heap's linked list as explained below, these freed blocks are also filled with a known value. Derzeit werden die folgenden Bytewerte verwendet:Currently, the actual byte values used are as follows:

NoMansLand (0xFD) die "NoMansLand"-Puffer auf beiden Seiten des Speichers, der von einer Anwendung verwendet wird, sind zurzeit mit "0xFD" gefüllt.NoMansLand (0xFD) The "NoMansLand" buffers on either side of the memory used by an application are currently filled with 0xFD.

Freigegebene Blöcke (0xDD) die freigegebenen Blöcke, die in der verknüpften Liste des Debugheaps nicht verwendet werden, wenn das _CRTDBG_DELAY_FREE_MEM_DF-Flag festgelegt ist, sind momentan mit 0xDD gefülltFreed blocks (0xDD) The freed blocks kept unused in the debug heap's linked list when the _CRTDBG_DELAY_FREE_MEM_DF flag is set are currently filled with 0xDD.

Neue Objekte (0xCD) neue Objekte werden mit 0xCD gefüllt, wenn Sie zugeordnet werden.New objects (0xCD) New objects are filled with 0xCD when they are allocated.

Zurück zum obersten InhaltBack to top Contents

Blocktypen auf dem DebugheapTypes of blocks on the debug heap

Jeder Speicherblock im Debugheap hat einen von fünf möglichen Reservierungstypen.Every memory block in the debug heap is assigned to one of five allocation types. Die Typen werden abhängig von der jeweiligen Aufgabe, z. B. Erkennung von Speicherverlusten und Erstellung von Zustandsberichten, auf unterschiedliche Weise nachverfolgt und ausgegeben.These types are tracked and reported differently for purposes of leak detection and state reporting. Sie legen den Blocktyp fest, indem Sie ihn durch den direkten Aufruf der Debug-Heapzuweisungsfunktion zuweisen, z.B. _malloc_dbg.You can specify a block's type by allocating it using a direct call to one of the debug heap allocation functions such as _malloc_dbg. Es gibt die folgenden fünf Speicherblocktypen im Debugheap (sie werden im Member nBlockUse der Struktur _CrtMemBlockHeader festgelegt):The five types of memory blocks in the debug heap (set in the nBlockUse member of the _CrtMemBlockHeader structure) are as follows:

_NORMAL_BLOCK Ein " malloc " oder " czuweisung "-Block erstellt einen normalen Block._NORMAL_BLOCK A call to malloc or calloc creates a Normal block. Wenn Sie ausschließlich normale Blöcke verwenden möchten und keine Clientblöcke benötigen, können Sie _CRTDBG_MAP_ALLOC definieren, wodurch alle Heapzuweisungsaufrufe ihren Debugäquivalenten in Debugbuilds zugeordnet werden.If you intend to use Normal blocks only, and have no need for Client blocks, you may want to define _CRTDBG_MAP_ALLOC, which causes all heap allocation calls to be mapped to their debug equivalents in Debug builds. Auf diese Weise können die Dateinamen und Zeilennummern zu jedem Reservierungsaufruf im entsprechenden Blockheader gespeichert werden.This will allow file name and line number information about each allocation call to be stored in the corresponding block header.

_CRT_BLOCK Die Speicherblöcke, die intern von zahlreichen Laufzeitbibliotheksfunktionen reserviert werden, sind als CRT-Blöcke gekennzeichnet und können daher gesondert behandelt werden._CRT_BLOCK The memory blocks allocated internally by many run-time library functions are marked as CRT blocks so they can be handled separately. So haben sie auf die Erkennung von Speicherverlusten und andere Operationen u. U. keinen Einfluss.As a result, leak detection and other operations need not be affected by them. CRT-Blöcke werden zu keiner Zeit durch eine Reservierungsoperation zugeordnet, erneut reserviert oder freigegeben.An allocation must never allocate, reallocate, or free any block of CRT type.

_CLIENT_BLOCK Eine Anwendung kann eine bestimmte Reservierungsgruppe zu Debugzwecken auf besondere Weise nachverfolgen, indem sie diese unter Verwendung expliziter Debugheap-Funktionsaufrufe als Speicherblöcke eines bestimmten Typs reserviert._CLIENT_BLOCK An application can keep special track of a given group of allocations for debugging purposes by allocating them as this type of memory block, using explicit calls to the debug heap functions. Beispielsweise belegt MFC alle CObjects als Clientblöcke, während andere Anwendungen andere Speicherobjekte in Clientblöcken verwalten können.MFC, for example, allocates all CObjects as Client blocks; other applications might keep different memory objects in Client blocks. Um die Nachverfolgung feiner abzustufen, können auch Untertypen von Clientblöcken definiert werden.Subtypes of Client blocks can also be specified for greater tracking granularity. Untertypen von Clientblöcken werden festgelegt, indem Sie die Zahl um 16 Bits nach links verschieben und eine OR-Operation mit _CLIENT_BLOCK ausführen.To specify subtypes of Client blocks, shift the number left by 16 bits and OR it with _CLIENT_BLOCK. Beispiel:For example:

#define MYSUBTYPE 4
freedbg(pbData, _CLIENT_BLOCK|(MYSUBTYPE<<16));

Eine vom Client bereitgestellte Hookfunktion zum Ausgeben der in Clientblöcken gespeicherten Objekte kann mithilfe von _CrtSetDumpClient installiert werden. Sie wird immer dann aufgerufen, wenn ein Clientblock durch eine Debugfunktion als Dump ausgegeben wird.A client-supplied hook function for dumping the objects stored in Client blocks can be installed using _CrtSetDumpClient, and will then be called whenever a Client block is dumped by a debug function. Auch _CrtDoForAllClientObjects kann dazu verwendet werden, eine bestimmte Funktion der Anwendung für jeden Clientblock im Debugheap aufzurufen.Also, _CrtDoForAllClientObjects can be used to call a given function supplied by the application for every Client block in the debug heap.

_FREE_BLOCK Normalerweise werden Blöcke, die freigegeben werden, aus der Liste entfernt._FREE_BLOCK Normally, blocks that are freed are removed from the list. Wenn Sie jedoch überprüfen möchten, ob weiterhin in freigegebene Blöcke geschrieben wird, oder wenn Sie Speichermangel simulieren möchten, können Sie die freigegebenen Blöcke auch weiterhin in der verknüpften Liste belassen. Diese Blöcke werden dann als freigegeben gekennzeichnet und mit einem definierten Bytewert (derzeit 0xDD) gefüllt.To check that freed memory is not still being written to or to simulate low memory conditions, you can choose to keep freed blocks on the linked list, marked as Free and filled with a known byte value (currently 0xDD).

_IGNORE_BLOCK Es ist möglich, die Debug-Heap Vorgänge für einen bestimmten Zeitraum zu deaktivieren._IGNORE_BLOCK It is possible to turn off the debug heap operations for a period of time. In diesem Zeitraum werden die Speicherblöcke zwar in der Liste geführt, aber als ignorierte Blöcke gekennzeichnet.During this time, memory blocks are kept on the list, but are marked as Ignore blocks.

Um den Typ und Untertyp eines bestimmten Blocks zu bestimmen, verwenden Sie die _CrtReportBlockType-Funktion sowie die Makros _BLOCK_TYPE und _BLOCK_SUBTYPE.To determine the type and subtype of a given block, use the function _CrtReportBlockType and the macros _BLOCK_TYPE and _BLOCK_SUBTYPE. Die Makros sind wie folgt (in crtdbg.h) definiert:The macros are defined (in crtdbg.h), as follows:

#define _BLOCK_TYPE(block)          (block & 0xFFFF)
#define _BLOCK_SUBTYPE(block)       (block >> 16 & 0xFFFF)

Zurück zum obersten InhaltBack to top Contents

Überprüfen auf Heapintegrität und SpeicherverlusteCheck for heap integrity and memory leaks

Auf viele Features des Debugheaps muss über den Code zugegriffen werden.Many of the debug heap's features must be accessed from within your code. Im folgenden Abschnitt werden einige Funktionen und ihre Verwendung beschrieben.The following section describes some of the features and how to use them.

_CrtCheckMemory Die Heapintegrität kann beispielsweise jederzeit mit einem Aufruf von _CrtCheckMemory überprüft werden._CrtCheckMemory You can use a call to _CrtCheckMemory, for example, to check the heap's integrity at any point. Diese Funktion liest jeden Speicherblock im Heap, überprüft die Headerinformationen im Speicherblock auf ihre Gültigkeit und bestätigt, dass die Puffer nicht geändert wurden.This function inspects every memory block in the heap, verifies that the memory block header information is valid, and confirms that the buffers have not been modified.

_CrtSetDbgFlag Mit dem internen _crtDbgFlag-Flag kann gesteuert werden, wie Zuweisungen vom Debugheap nachverfolgt werden. Das Flag kann mit der _CrtSetDbgFlag-Funktion gelesen und festgelegt werden._CrtSetDbgFlag You can control how the debug heap keeps track of allocations using an internal flag, _crtDbgFlag, which can be read and set using the _CrtSetDbgFlag function. Indem Sie dieses Flag ändern, können Sie den Debugheap anweisen, beim Beenden des Programms mögliche Speicherverluste zu ermitteln und ggf. einen Speicherverlustbericht auszugeben.By changing this flag, you can instruct the debug heap to check for memory leaks when the program exits and report any leaks that are detected. Entsprechend können Sie festlegen, dass freigegebene Speicherblöcke nicht aus der verknüpften Liste entfernt werden, um beispielsweise Speichermangel zu simulieren.Similarly, you can specify that freed memory blocks not be removed from the linked list, to simulate low-memory situations. Beim Überprüfen des Heaps werden die freigegebenen Blöcke insgesamt kontrolliert, um sicherzustellen, dass sie nicht behindert wurden.When the heap is checked, these freed blocks are inspected in their entirety to ensure that they have not been disturbed.

Das _crtDbgFlag-Flag enthält die folgenden Bitfelder:The _crtDbgFlag flag contains the following bit fields:

BitfeldBit field DefaultDefault

Wertvalue
BeschreibungDescription
_CRTDBG_ALLOC_MEM_DF_CRTDBG_ALLOC_MEM_DF EinOn Aktiviert die Debugreservierung.Turns on debug allocation. Wenn dieses Bit deaktiviert ist, bleiben die belegten Blöcke weiterhin verknüpft, ihr Blocktyp wird jedoch zu _IGNORE_BLOCK.When this bit is off, allocations remain chained together but their block type is _IGNORE_BLOCK.
_CRTDBG_DELAY_FREE_MEM_DF_CRTDBG_DELAY_FREE_MEM_DF AusOff Verhindert die Freigabe von Speicher, um beispielsweise Speichermangel zu simulieren.Prevents memory from actually being freed, as for simulating low-memory conditions. Wenn dieses Bit aktiviert ist, werden die freigegebenen Blöcke weiterhin in der verknüpften Liste verwaltet, jedoch als _FREE_BLOCK gekennzeichnet und mit einem definierten Bytewert gefüllt.When this bit is on, freed blocks are kept in the debug heap's linked list but are marked as _FREE_BLOCK and filled with a special byte value.
_CRTDBG_CHECK_ALWAYS_DF_CRTDBG_CHECK_ALWAYS_DF AusOff Bewirkt den Aufruf von _CrtCheckMemory bei jeder Speicherbelegung und jedem Aufheben der Speicherbelegung.Causes _CrtCheckMemory to be called at every allocation and deallocation. Dies verlangsamt zwar die Ausführung, beschleunigt aber die Fehlersuche.This slows execution, but catches errors quickly.
_CRTDBG_CHECK_CRT_DF_CRTDBG_CHECK_CRT_DF AusOff Bewirkt, dass Blöcke vom Typ _CRT_BLOCK in Operationen, die Speicherverluste und unterschiedliche Zustände feststellen sollen, eingeschlossen werden.Causes blocks marked as type _CRT_BLOCK to be included in leak-detection and state-difference operations. Wenn dieses Bit deaktiviert ist, wird der von der Laufzeitbibliothek intern verwendete Speicher während solcher Operationen ignoriert.When this bit is off, the memory used internally by the run-time library is ignored during such operations.
_CRTDBG_LEAK_CHECK_DF_CRTDBG_LEAK_CHECK_DF AusOff Bewirkt, dass Überprüfungen auf Speicherverluste beim Beenden des Programms durch einen _CrtDumpMemoryLeaks-Aufruf durchgeführt werden.Causes leak checking to be performed at program exit via a call to _CrtDumpMemoryLeaks. Wenn die Anwendung nicht den gesamten belegten Speicher freigeben konnte, wird ein Fehlerbericht generiert.An error report is generated if the application has failed to free all the memory that it allocated.

Zurück zum obersten InhaltBack to top Contents

Konfigurieren des DebugheapsConfigure the debug heap

Alle Aufrufe an Heapfunktionen, wie z. B. malloc, free, calloc, realloc, new und delete, werden in die Debugversionen der Funktionen aufgelöst, die auf dem Debugheap arbeiten.All calls to heap functions such as malloc, free, calloc, realloc, new, and delete resolve to debug versions of those functions that operate in the debug heap. Wenn Sie einen Speicherblock freigeben, überprüft der Debugheap automatisch die Pufferintegrität auf beiden Seiten des reservierten Bereichs und erstellt einen Fehlerbericht, falls über den Puffer hinaus geschrieben wurde.When you free a memory block, the debug heap automatically checks the integrity of the buffers on either side of your allocated area and issues an error report if overwriting has occurred.

So verwenden Sie den DebugheapTo use the debug heap

  • Verknüpfen Sie das Debugbuild der Anwendung mit einer Debugversion der C-Laufzeitbibliothek.Link the debug build of your application with a debug version of the C run-time library.

    So ändern Sie eines oder mehrere _crtDbgFlag-Bitfelder sowie den FlagzustandTo change one or more _crtDbgFlag bit fields and create a new state for the flag

  1. Rufen Sie _CrtSetDbgFlag auf, wobei der newFlag-Parameter auf _CRTDBG_REPORT_FLAG festgelegt ist (um den aktuellen _crtDbgFlag-Zustand zu erhalten), und speichern Sie den Rückgabewert in einer temporären Variablen.Call _CrtSetDbgFlag with the newFlag parameter set to _CRTDBG_REPORT_FLAG (to obtain the current _crtDbgFlag state) and store the returned value in a temporary variable.

  2. Schalten Sie alle Bits ein, indem Sie die temporäre Variable mit | den entsprechenden Bitmasken (die im Anwendungscode durch Manifest-Konstanten dargestellt werden) OR (bitweises Symbol).Turn on any bits by OR-ing (bitwise | symbol) the temporary variable with the corresponding bitmasks (represented in the application code by manifest constants).

  3. Deaktivieren Sie die anderen Bits, indem Sie die Variable mit einem NOT (bitweises ~ Symbol) der entsprechenden Bitmasks AND (Bitweises & Symbol).Turn off the other bits by AND-ing (bitwise & symbol) the variable with a NOT (bitwise ~ symbol) of the appropriate bitmasks.

  4. Rufen Sie _CrtSetDbgFlag auf, wobei der newFlag-Parameter auf den in der temporären Variablen gespeicherten Wert festgelegt ist, um den neuen Zustand von _crtDbgFlag festzulegen.Call _CrtSetDbgFlag with the newFlag parameter set to the value stored in the temporary variable to create the new state for _crtDbgFlag.

    Beispielsweise wird durch die folgenden Codezeilen die automatische Überprüfung auf Speicherverluste aktiviert und die Überprüfung von _CRT_BLOCK-Blöcken deaktiviert:For example, the following lines of code turn on automatic leak detection and turn off checking for blocks of type _CRT_BLOCK:

// Get current flag
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );

// Turn on leak-checking bit.
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;

// Turn off CRT block checking bit.
tmpFlag &= ~_CRTDBG_CHECK_CRT_DF;

// Set flag to the new value.
_CrtSetDbgFlag( tmpFlag );

Zurück zum obersten InhaltBack to top Contents

„new“, „delete“ und „_CLIENT_BLOCK“ im C++-Debugheapnew, delete, and _CLIENT_BLOCKs in the C++ debug heap

Die Debugversionen der C-Laufzeitbibliothek enthalten Debugversionen der new- und delete-C++-Operatoren.The debug versions of the C run-time library contain debug versions of the C++ new and delete operators. Bei Verwendung des _CLIENT_BLOCK-Zuweisungstyps müssen Sie die Debugversion des new-Operators direkt aufrufen oder Makros erstellen, die den new-Operator im Debugmodus ersetzen, wie im folgenden Beispiel dargestellt:If you use the _CLIENT_BLOCK allocation type, you must call the debug version of the new operator directly or create macros that replace the new operator in debug mode, as shown in the following example:

/* MyDbgNew.h
 Defines global operator new to allocate from
 client blocks
*/

#ifdef _DEBUG
   #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
   #define DEBUG_CLIENTBLOCK
#endif // _DEBUG

/* MyApp.cpp
        Use a default workspace for a Console Application to
 *      build a Debug version of this code
*/

#include "crtdbg.h"
#include "mydbgnew.h"

#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif

int main( )   {
    char *p1;
    p1 =  new char[40];
    _CrtMemDumpAllObjectsSince( NULL );
}

Die Debugversion des Operators delete funktioniert mit allen Blocktypen und macht daher bei der Kompilierung einer Releaseversion keine Programmänderungen erforderlich.The Debug version of the delete operator works with all block types and requires no changes in your program when you compile a Release version.

Zurück zum obersten InhaltBack to top Contents

Berichtsfunktionen für den HeapzustandHeap State Reporting Functions

_CrtMemState_CrtMemState

Um zu einem bestimmten Zeitpunkt eine zusammenfassende Momentaufnahme des Heapzustands aufzuzeichnen, verwenden Sie die in CRTDBG.H definierte _CrtMemState-Struktur:To capture a summary snapshot of the state of the heap at a given time, use the _CrtMemState structure defined in CRTDBG.H:

typedef struct _CrtMemState
{
    // Pointer to the most recently allocated block:
    struct _CrtMemBlockHeader * pBlockHeader;
    // A counter for each of the 5 types of block:
    size_t lCounts[_MAX_BLOCKS];
    // Total bytes allocated in each block type:
    size_t lSizes[_MAX_BLOCKS];
    // The most bytes allocated at a time up to now:
    size_t lHighWaterCount;
    // The total bytes allocated at present:
    size_t lTotalCount;
} _CrtMemState;

Diese Struktur speichert einen Zeiger auf den ersten (zuletzt reservierten) Block in der verknüpften Heapliste.This structure saves a pointer to the first (most recently allocated) block in the debug heap's linked list. Anschließend zeichnet sie in zwei Arrays auf, wie viele Speicherblöcke jedes Typs (_NORMAL_BLOCK, _CLIENT_BLOCK, _FREE_BLOCK usw.) sich in der Liste befinden und wie viele Bytes für jeden Blocktyp reserviert wurden.Then, in two arrays, it records how many of each type of memory block (_NORMAL_BLOCK, _CLIENT_BLOCK, _FREE_BLOCK, and so on) are in the list and the number of bytes allocated in each type of block. Schließlich zeichnet die Struktur auf, wie viele Bytes bisher maximal gleichzeitig im Heap reserviert waren und wie viele Bytes momentan reserviert sind.Finally, it records the highest number of bytes allocated in the heap as a whole up to that point, and the number of bytes currently allocated.

Andere CRT‑BerichtsfunktionenOther CRT Reporting Functions

Die folgenden Funktionen geben den Heapzustand und -inhalt wieder. Diese Informationen werden verwendet, um Speicherverluste und andere Probleme zu erkennen.The following functions report the state and contents of the heap, and use the information to help detect memory leaks and other problems.

FunktionFunction BeschreibungDescription
_CrtMemCheckpoint_CrtMemCheckpoint Speichert eine Heapmomentaufnahme in einer von der Anwendung bereitgestellten _CrtMemState-Struktur.Saves a snapshot of the heap in a _CrtMemState structure supplied by the application.
_CrtMemDifference_CrtMemDifference Vergleicht zwei Speicherzustandsstrukturen, speichert die Unterschiede in einer dritten Zustandsstruktur und gibt TRUE zurück, falls unterschiedliche Zustände festgestellt wurden.Compares two memory state structures, saves the difference between them in a third state structure, and returns TRUE if the two states are different.
_CrtMemDumpStatistics_CrtMemDumpStatistics Gibt eine bestimmte _CrtMemState-Struktur aus.Dumps a given _CrtMemState structure. Die Struktur kann eine Zustandsmomentaufnahme des Debugheaps oder die Unterschiede zwischen zwei Momentaufnahmen enthalten.The structure may contain a snapshot of the state of the debug heap at a given moment or the difference between two snapshots.
_CrtMemDumpAllObjectsSince_CrtMemDumpAllObjectsSince Gibt Informationen zu allen Objekten aus, die seit einer bestimmten Heapmomentaufnahme oder seit Beginn der Ausführung reserviert wurden.Dumps information about all objects allocated since a given snapshot was taken of the heap or from the start of execution. Bei jedem Dump eines _CLIENT_BLOCK-Blocks wird eine von der Anwendung bereitgestellte Hookfunktion aufgerufen, falls eine solche mit _CrtSetDumpClient installiert wurde.Every time it dumps a _CLIENT_BLOCK block, it calls a hook function supplied by the application, if one has been installed using _CrtSetDumpClient.
_CrtDumpMemoryLeaks_CrtDumpMemoryLeaks Stellt fest, ob seit dem Programmstart Speicherverluste aufgetreten sind, und gibt ggf. alle reservierten Objekte aus.Determines whether any memory leaks occurred since the start of program execution and, if so, dumps all allocated objects. Wenn _CrtDumpMemoryLeaks einen _CLIENT_BLOCK-Block ausgibt, wird eine von der Anwendung bereitgestellte Hookfunktion aufgerufen, falls eine solche mit _CrtSetDumpClient installiert wurde.Every time _CrtDumpMemoryLeaks dumps a _CLIENT_BLOCK block, it calls a hook function supplied by the application, if one has been installed using _CrtSetDumpClient.

Zurück zum obersten InhaltBack to top Contents

Nachverfolgen von HeapzuweisungsanforderungenTrack Heap Allocation Requests

Die Angabe des Quelldateinamens und der Zeilennummer, in der eine Assertion oder ein Berichtsmakro ausgeführt wird, ist häufig sehr nützlich, um die Fehlerursache festzustellen. Auf Heapreservierungsfunktionen trifft dies in der Regel jedoch nicht zu.Although pinpointing the source file name and line number at which an assert or reporting macro executes is often very useful in locating the cause of a problem, the same is not as likely to be true of heap allocation functions. Makros können an vielen geeigneten Stellen in der logischen Struktur einer Anwendung eingefügt werden, während eine Reservierung meist in einer speziellen Routine verborgen wird, die zu unterschiedlichen Zeitpunkten von vielen verschiedenen Stellen aus aufgerufen wird.While macros can be inserted at many appropriate points in an application's logic tree, an allocation is often buried in a special routine that is called from many different places at many different times. Die Frage ist in der Regel nicht, welche Codezeile eine Fehlreservierung verursacht, sondern welche der vielen tausend Reservierungen durch diese Codezeile fehlerhaft waren und warum.The question is usually not what line of code made a bad allocation, but rather which one of the thousands of allocations made by that line of code was bad and why.

Eindeutige Zuweisungsanforderungsnummern und „_crtBreakAlloc“Unique Allocation Request Numbers and _crtBreakAlloc

Der gesuchte falsche Heapreservierungsaufruf lässt sich am besten feststellen, wenn man die eindeutige Reservierungsanforderungsnummer jedes Blocks im Debugheap berücksichtigt.The simplest way to identify the specific heap allocation call that went bad is to take advantage of the unique allocation request number associated with each block in the debug heap. Wenn Blockinformationen über eine der Dumpfunktionen ausgegeben werden, wird die Zuweisungsanforderungsnummer in geschweiften Klammern angezeigt (Beispiel: {36}).When information about a block is reported by one of the dump functions, this allocation request number is enclosed in braces (for example, "{36}").

Wenn Sie die Zuweisungsanforderungsnummer eines falsch zugewiesenen Blocks kennen, können Sie diese Nummer an _CrtSetBreakAlloc übergeben, um einen Haltepunkt zu erstellen.Once you know the allocation request number of an improperly allocated block, you can pass this number to _CrtSetBreakAlloc to create a breakpoint. Die Ausführung wird dann unmittelbar vor der Reservierung des betreffenden Blocks unterbrochen, und Sie können zurückverfolgen, welche Routine für den falschen Aufruf verantwortlich ist.Execution will break just before allocating the block, and you can backtrack to determine what routine was responsible for the bad call. Um eine erneute Kompilierung zu vermeiden, können Sie im Debugger genauso verfahren, indem Sie _crtBreakAlloc auf die gewünschte Zuweisungsanforderungsnummer festlegen.To avoid recompiling, you can accomplish the same thing in the debugger by setting _crtBreakAlloc to the allocation request number you are interested in.

Erstellen von Debugversionen von ZuweisungsroutinenCreating Debug Versions of Your Allocation Routines

Etwas komplizierter ist ein anderes Verfahren, bei dem Sie Debugversionen eigener Zuweisungsroutinen erstellen. Diese sind vergleichbar mit den _dbg-Versionen der Heapzuweisungsfunktionen.A somewhat more complicated approach is to create Debug versions of your own allocation routines, comparable to the _dbg versions of the heap allocation functions. Sie können dann den Quelldateinamen und die Zeilennummer als Argumente an die zugrunde liegenden Heapreservierungsroutinen übergeben und sofort den Ursprung einer Fehlreservierung feststellen.You can then pass source file and line number arguments through to the underlying heap allocation routines, and you will immediately be able to see where a bad allocation originated.

Angenommen, die Anwendung enthält eine häufig verwendete Routine, die etwa wie folgt aussieht:For example, suppose your application contains a commonly used routine similar to the following:

int addNewRecord(struct RecStruct * prevRecord,
                 int recType, int recAccess)
{
    // ...code omitted through actual allocation...
    if ((newRec = malloc(recSize)) == NULL)
    // ... rest of routine omitted too ...
}

In einer Headerdatei können Sie dann beispielsweise folgenden Code hinzufügen:In a header file, you could add code such as the following:

#ifdef _DEBUG
#define  addNewRecord(p, t, a) \
            addNewRecord(p, t, a, __FILE__, __LINE__)
#endif

Als nächstes ändern Sie die Reservierung in der Routine zum Erstellen von Datensätzen wie folgt:Next, you could change the allocation in your record-creation routine as follows:

int addNewRecord(struct RecStruct *prevRecord,
                int recType, int recAccess
#ifdef _DEBUG
               , const char *srcFile, int srcLine
#endif
    )
{
    /* ... code omitted through actual allocation ... */
    if ((newRec = _malloc_dbg(recSize, _NORMAL_BLOCK,
            srcFile, scrLine)) == NULL)
    /* ... rest of routine omitted too ... */
}

Nun werden der Quelldateiname und die Zeilennummer, in der addNewRecord aufgerufen wurde, in jedem dadurch reservierten Block im Debugheap gespeichert und beim Überprüfen des Blocks ausgegeben.Now the source file name and line number where addNewRecord was called will be stored in each resulting block allocated in the debug heap and will be reported when that block is examined.

Zurück zum obersten InhaltBack to top Contents

Siehe auchSee also

Debuggen von nativem CodeDebugging Native Code