Dire que j'ai un tableau de caractères C char buf[15]
. La variable Say int set_me = 0
a ses données stockées dans un emplacement de mémoire directement après char buf[15]
. Si je débordais buf
de ficelle "aaabbbcccdddeee\xef\xbe\xad\xde"
,set_me
le type de données changerait-il d'un entier à un tableau de caractères?
8
Réponses:
Non.
Le "type de données" d'une variable n'est pertinent que dans le code source (et même alors seulement dans certaines langues). Il indique au compilateur comment traiter la variable.
Ces types de données de haut niveau n'existent pas en tant que tels dans le code compilé (natif). Ils peuvent affecter les instructions qu'un compilateur génère, mais les instructions elles-mêmes ne se soucient pas si les données représentent un caractère ou un nombre.
Les variables n'existent pas dans le matériel. Dans le matériel, vous avez des emplacements de mémoire et les instructions qui les concernent.
Une variable peut être vue comme une vue des données à un emplacement mémoire - si vous plissez les yeux et regardez la même mémoire légèrement différemment (une variable différente avec un type différent se référant au même emplacement), la même valeur binaire peut avoir une signification différente .
Par exemple, l'octet 0x41 pourrait être interprété comme le caractère codé UTF-8
A
. Il pourrait également être interprété comme l'entier à un octet65
. Il peut également être interprété comme un octet dans un entier à plusieurs octets ou un nombre à virgule flottante, ou un octet dans un codage de caractères à plusieurs octets. Ce pourrait être le jeu de bits0b1000001
. Tous à partir du même octet dans le même emplacement de mémoire. En langage C, vous pouvez voir cet effet en effectuant un cast sur ces différents types.Lorsque vous avez un "débordement de tampon", vous faites quelque chose en dehors des limites de ce à quoi votre compilateur ou votre langage peut s'attendre. Mais, en ce qui concerne le matériel 1 , vous écrivez des octets (simples ou multiples) dans un emplacement mémoire. Un emplacement mémoire n'a pas de "type". En fait, le matériel ne sait même pas qu'un ensemble particulier d'octets crée un tableau ou un tampon dans votre code.
Où que vous accédiez à cet emplacement de mémoire dans votre code, les instructions s'exécuteront comme défini à l'origine. par exemple, s'ils s'attendaient à un nombre, ils agiront sur tous les octets de données comme s'ils étaient un nombre.
Pour utiliser votre exemple, en supposant que votre
int
est un entier signé sur 4 octets (32 bits):Vous pouvez voir que l'
int
emplacement mémoire du contient maintenant0xEFBEADDE
, en supposant un système big-endian 2 . Il s'agit de l'intégré 32 bits signé-272716322
. Maintenant, si vous interprétez la même mémoire comme un int (uint
) non signé , ce serait à la4022250974
place. Pour exactement les mêmes données en mémoire, la signification dépend entièrement de la façon dont vous les voyez.1 Certains mécanismes vous empêchent d'écrire dans des régions protégées de la mémoire et plantent votre programme si vous essayez de le faire.
2 x86 est en fait peu-endian, ce qui signifie que vous interprétez les octets constituant une plus grande valeur à l'envers. Donc, sur x86, vous auriez à la place
0xDEADBEEF
, donnant signé-559038737
ou non signé3735928559
.la source
0xdeadbeef
, sur une architecture x86, prendrait moins de place en mémoire que son homologue décimal,3735928559
?0xDEADBEEF
est stockée en mémoire sous la forme0x30 0x78 0x44 0x45 0x41 0x44 0x42 0x45 0x45 0x46
.0xEFBEADDE
. Peut-être reformulez-le un peu. Sinon, c'est une superbe réponse - j'aime particulièrement l'analogie "voir" et l'idée "plisser les yeux" :)Du point de vue C, la réponse serait "Qui sait? C'est un comportement indéfini".
Les types sont un concept C, pas du matériel. Mais les règles C ne s'appliquent pas si votre programme a un comportement indéfini, c'est la signification littérale du comportement indéfini dans la norme C. Et les dépassements de tampon en sont une forme.
J'ai d'abord écrit "les règles C ne s'appliquent plus", mais en fait le comportement indéfini est rétroactif. Les règles C ne s'appliquent pas à un programme qui aura un comportement indéfini à l'avenir.
la source