Un bref résumé de ce que les compilateurs de Microsoft utilisent pour divers bits de mémoire non possédés/non initialisés lorsqu'ils sont compilés en mode débogage (le support peut varier en fonction de la version du compilateur) :
Valeur Nom Description
------ -------- -------------------------
0xCD Mémoire propre Mémoire allouée via malloc ou new mais jamais
écrite par l'application.
0xDD Mémoire morte Mémoire qui a été libérée avec delete ou free.
Elle est utilisée pour détecter l'écriture à travers des pointeurs erronés.
0xED ou Barrière alignée 'Terre de personne' pour des allocations alignées. Utiliser une
0xBD valeur différente ici que 0xFD permet au runtime
de détecter non seulement l'écriture en dehors de l'allocation,
mais aussi d'identifier le mélange des routines d'allocation/désallocation
spécifiques à l'alignement avec les routines régulières.
0xFD Mémoire barrière Aussi connu sous le nom de "terre de personne." Cela sert à envelopper
la mémoire allouée (l'entourant d'une barrière)
et est utilisé pour détecter les accès aux tableaux en dehors
des limites ou autres accès (surtout écritures) au-delà
de la fin (ou du début) d'un bloc alloué.
0xFD ou Espace tampon Utilisé pour remplir l'espace tampon dans certains tampons mémoire
0xFE (parties inutilisées de `std::string` ou le tampon utilisateur
passé à `fread()`). 0xFD est utilisé dans VS 2005 (peut-être
également dans certaines versions antérieures), 0xFE est utilisé dans
VS 2008 et ultérieur.
0xCC Lorsque le code est compilé avec l'option /GZ,
les variables non initialisées sont automatiquement assignées
à cette valeur (au niveau octet).
// les valeurs magiques suivantes sont faites par le système d'exploitation, pas par le runtime C :
0xAB Bloc alloué Memory allouée par LocalAlloc().
0xBAADF00D Mauvaise valeur Mémoire allouée par LocalAlloc() avec LMEM_FIXED, mais
pas encore écrite.
0xFEEEFEEE Mémoire de tas remplie par le système d'exploitation, marquée pour être utilisée,
mais qui n'a pas été allouée par HeapAlloc() ou LocalAlloc().
Ou cette mémoire vient d'être libérée par HeapFree().
Avertissement : le tableau provient de notes que j'ai traînant quelque part - elles peuvent ne pas être à 100% correctes (ou cohérentes).
Nombre de ces valeurs sont définies dans vc/crt/src/dbgheap.c :
/*
* Les valeurs suivantes sont non nulles, constantes, impaires, grandes et atypiques
* Les valeurs non nulles aident à trouver des bugs en supposant des données remplies de zéros.
* Les valeurs constantes sont bonnes, de sorte que le remplissage de mémoire soit déterministe
* (pour aider à rendre les bugs reproductibles). Bien sûr, il est mauvais si
* le remplissage constant de valeurs étranges masque un bug.
* Les nombres mathématiquement impairs sont bons pour trouver des bugs en supposant un bit de poids faible effacé.
* Les grands nombres (valeurs d'octet au moins) sont moins typiques et sont bons
* pour trouver des mauvaises adresses.
* Les valeurs atypiques (c'est-à-dire pas trop souvent) sont bonnes car elles provoquent généralement
* une détection précoce dans le code.
* Dans le cas de la terre de personne et des blocs libres, si vous stockez dans l'un de ces
* emplacements, le vérificateur d'intégrité de mémoire le détectera.
*
* _bAlignLandFill a été changé de 0xBD à 0xED, pour s'assurer que
* 4 octets de cela (0xEDEDEDED) donneraient une adresse inaccessible en dessous de 3gb.
*/
static unsigned char _bNoMansLandFill = 0xFD; /* remplir la terre de personne avec ceci */
static unsigned char _bAlignLandFill = 0xED; /* remplir la terre de personne pour les routines alignées */
static unsigned char _bDeadLandFill = 0xDD; /* remplir les objets libres avec ceci */
static unsigned char _bCleanLandFill = 0xCD; /* remplir les nouveaux objets avec ceci */
Il y a aussi quelques cas où le runtime débogage remplira des tampons (ou des parties de tampons) avec une valeur connue, par exemple, l'espace 'slack' dans l'allocation de std::string
ou le tampon passé à fread()
. Ces cas utilisent une valeur nommée _SECURECRT_FILL_BUFFER_PATTERN
(définie dans crtdefs.h
). Je ne sais pas exactement quand elle a été introduite, mais elle était présente dans le runtime débogage au moins à partir de VS 2005 (VC++8).
Initialement, la valeur utilisée pour remplir ces tampons était 0xFD
- la même valeur utilisée pour la terre de personne. Cependant, dans VS 2008 (VC++9) la valeur a été changée en 0xFE
. Je suppose que c'est parce qu'il pourrait y avoir des situations où l'opération de remplissage déborderait de la fin du tampon, par exemple, si l'appelant passait une taille de tampon qui était trop grande à fread()
. Dans ce cas, la valeur 0xFD
peut ne pas déclencher la détection de ce dépassement puisque si la taille du tampon était trop grande de seulement un, la valeur de remplissage serait la même que la valeur de terre de personne utilisée pour l'initialisation de ce chas. Aucun changement dans la terre de personne signifie que le dépassement ne serait pas remarqué.
Ainsi, la valeur de remplissage a été changée dans VS 2008 de sorte que dans un tel cas le chas de la terre de personne changerait, entraînant la détection du problème par le runtime.
Comme d'autres l'ont noté, l'une des propriétés clés de ces valeurs est que si une variable pointeur avec l'une de ces valeurs est déréférencée, cela entraînera une violation d'accès, puisque dans une configuration Windows 32 bits standard, les adresses en mode utilisateur n'iront pas au-delà de 0x7fffffff.