Eine kurze Zusammenfassung dessen, was Microsoft-Compiler für verschiedene Teile des nicht besessenen / nicht initialisierten Speichers verwenden, wenn sie für den Debug-Modus kompiliert werden (die Unterstützung kann je nach Compiler-Version variieren):
Value Name Description
------ -------- -------------------------
0xCD Clean Memory Allocated memory via malloc or new but never
written by the application.
0xDD Dead Memory Memory that has been released with delete or free.
It is used to detect writing through dangling pointers.
0xED or Aligned Fence 'No man's land' for aligned allocations. Using a
0xBD different value here than 0xFD allows the runtime
to detect not only writing outside the allocation,
but to also identify mixing alignment-specific
allocation/deallocation routines with the regular
ones.
0xFD Fence Memory Also known as "no mans land." This is used to wrap
the allocated memory (surrounding it with a fence)
and is used to detect indexing arrays out of
bounds or other accesses (especially writes) past
the end (or start) of an allocated block.
0xFD or Buffer slack Used to fill slack space in some memory buffers
0xFE (unused parts of `std::string` or the user buffer
passed to `fread()`). 0xFD is used in VS 2005 (maybe
some prior versions, too), 0xFE is used in VS 2008
and later.
0xCC When the code is compiled with the /GZ option,
uninitialized variables are automatically assigned
to this value (at byte level).
// the following magic values are done by the OS, not the C runtime:
0xAB (Allocated Block?) Memory allocated by LocalAlloc().
0xBAADF00D Bad Food Memory allocated by LocalAlloc() with LMEM_FIXED,but
not yet written to.
0xFEEEFEEE OS fill heap memory, which was marked for usage,
but wasn't allocated by HeapAlloc() or LocalAlloc().
Or that memory just has been freed by HeapFree().
Haftungsausschluss: Die Tabelle stammt aus einigen Notizen, die ich herumliegen habe - sie sind möglicherweise nicht 100% korrekt (oder kohärent).
Viele dieser Werte sind in vc / crt / src / dbgheap.c definiert:
/*
* The following values are non-zero, constant, odd, large, and atypical
* Non-zero values help find bugs assuming zero filled data.
* Constant values are good, so that memory filling is deterministic
* (to help make bugs reproducible). Of course, it is bad if
* the constant filling of weird values masks a bug.
* Mathematically odd numbers are good for finding bugs assuming a cleared
* lower bit.
* Large numbers (byte values at least) are less typical and are good
* at finding bad addresses.
* Atypical values (i.e. not too often) are good since they typically
* cause early detection in code.
* For the case of no man's land and free blocks, if you store to any
* of these locations, the memory integrity checker will detect it.
*
* _bAlignLandFill has been changed from 0xBD to 0xED, to ensure that
* 4 bytes of that (0xEDEDEDED) would give an inaccessible address under 3gb.
*/
static unsigned char _bNoMansLandFill = 0xFD; /* fill no-man's land with this */
static unsigned char _bAlignLandFill = 0xED; /* fill no-man's land for aligned routines */
static unsigned char _bDeadLandFill = 0xDD; /* fill free objects with this */
static unsigned char _bCleanLandFill = 0xCD; /* fill new objects with this */
Es gibt auch einige Male, in denen die Debug-Laufzeit Puffer (oder Teile von Puffern) mit einem bekannten Wert füllt, z. B. dem "Slack" -Platz in std::string
der Zuweisung oder dem Puffer, an den übergeben wird fread()
. In diesen Fällen wird ein Wert mit dem Namen _SECURECRT_FILL_BUFFER_PATTERN
(definiert in crtdefs.h
) verwendet. Ich bin mir nicht sicher, wann es genau eingeführt wurde, aber es war in der Debug-Laufzeit von mindestens VS 2005 (VC ++ 8).
Anfangs war der Wert, der zum Füllen dieser Puffer verwendet wurde, 0xFD
der gleiche Wert, der für Niemandsland verwendet wurde. In VS 2008 (VC ++ 9) wurde der Wert jedoch in geändert 0xFE
. Ich nehme an, das liegt daran, dass es Situationen geben kann, in denen die Fülloperation über das Ende des Puffers hinaus ausgeführt wird, z. B. wenn der Aufrufer eine Puffergröße übergeben hat, die zu groß ist, um fread()
. In diesem Fall 0xFD
löst der Wert möglicherweise keine Erkennung dieses Überlaufs aus, da bei einer zu großen Puffergröße von nur eins der Füllwert dem Landwert des Niemands entspricht, der zum Initialisieren dieses Kanarienvogels verwendet wird. Keine Veränderung im Niemandsland bedeutet, dass der Überlauf nicht bemerkt wird.
Daher wurde der Füllwert in VS 2008 geändert, sodass in einem solchen Fall der Niemandslandkanarienvogel geändert wird, wodurch das Problem zur Laufzeit erkannt wird.
Wie andere angemerkt haben, besteht eine der Schlüsseleigenschaften dieser Werte darin, dass eine Zeigervariable mit einem dieser Werte, wenn die Referenzierung aufgehoben wird, zu einer Zugriffsverletzung führt, da in einer 32-Bit-Standardkonfiguration Benutzermodusadressen verwendet werden wird nicht höher als 0x7fffffff gehen.