Angenommen, ich habe ein C-Zeichen-Array char buf[15]
. Angenommen, die Variablen int set_me = 0
der Variablen werden direkt danach an einem Speicherort gespeichert char buf[15]
. Wenn ich buf
mit einer Zeichenfolge überlaufen "aaabbbcccdddeee\xef\xbe\xad\xde"
würde, würde sich set_me
der Datentyp von einer Ganzzahl in ein Zeichenarray ändern?
8
Antworten:
Nein.
Der "Datentyp" einer Variablen ist nur im Quellcode relevant (und selbst dann nur in einigen Sprachen). Es teilt dem Compiler mit, wie die Variable behandelt werden soll.
Diese übergeordneten Datentypen sind als solche im kompilierten (nativen) Code nicht vorhanden. Sie können sich darauf auswirken, welche Anweisungen ein Compiler generiert, aber den Anweisungen selbst ist es egal, ob die Daten ein Zeichen oder eine Zahl darstellen.
Variablen sind in der Hardware nicht vorhanden. In der Hardware haben Sie Speicherorte und die Anweisungen, die auf ihnen arbeiten.
Eine Variable kann als Ansicht der Daten an einem Speicherort angesehen werden. Wenn Sie denselben Speicher etwas anders betrachten (eine andere Variable mit unterschiedlichem Typ bezieht sich auf denselben Speicherort), kann derselbe Binärwert eine andere Bedeutung haben .
Beispielsweise könnte das Byte 0x41 als UTF-8-codiertes Zeichen interpretiert werden
A
. Es könnte auch als Einzelbyte-Ganzzahl interpretiert werden65
. Es könnte auch als ein Byte in einer Mehrbyte-Ganzzahl oder Gleitkommazahl oder als ein Byte in einer Mehrbyte-Zeichencodierung interpretiert werden. Es könnte das Bitset sein0b1000001
. Alle aus demselben Byte am selben Speicherort. In der C - Sprache, können Sie diesen Effekt sehen durch Gießen auf diese verschiedenen Arten.Wenn Sie einen "Pufferüberlauf" haben, tun Sie etwas außerhalb der Grenzen, die Ihr Compiler oder Ihre Sprache erwarten könnten. In Bezug auf die Hardware 1 schreiben Sie jedoch Bytes (einzeln oder mehrfach) in einen Speicherort. Ein Speicherort hat keinen "Typ". Tatsächlich weiß die Hardware nicht einmal, dass ein bestimmter Satz von Bytes ein Array oder einen Puffer in Ihrem Code bildet.
Wenn Sie das nächste Mal in Ihrem Code auf diesen Speicherort zugreifen, werden die Anweisungen wie ursprünglich definiert ausgeführt. Wenn sie dort beispielsweise eine Nummer erwartet haben, werden sie auf alle Datenbytes so reagieren, als wären sie eine Nummer.
Angenommen, es
int
handelt sich um eine vorzeichenbehaftete 4-Byte-Ganzzahl (32-Bit):Sie können sehen, dass der
int
Speicherort des 'jetzt0xEFBEADDE
unter der Annahme eines Big-Endian-Systems 2 enthält . Dies ist das vorzeichenbehaftete 32-Bit-Int-272716322
. Wenn Sie nun denselben Speicher wie ein vorzeichenloses int (uint
) interpretieren , ist dies4022250974
stattdessen der Fall . Für genau dieselben Daten im Speicher hängt die Bedeutung ganz davon ab, wie Sie sie anzeigen.1 Es gibt einige Mechanismen, die Sie daran hindern, in geschützte Speicherbereiche zu schreiben, und die Ihr Programm zum Absturz bringen, wenn Sie dies versuchen.
2 x86 ist eigentlich Little-Endian, was bedeutet, dass Sie die Bytes, aus denen sich ein größerer Wert zusammensetzt, rückwärts interpretieren. Auf x86 müssten Sie stattdessen
0xDEADBEEF
signiert-559038737
oder nicht signiert angeben3735928559
.quelle
0xdeadbeef
, auf einer x86 - Architektur, würde weniger Platz im Speicher als sein Dezimal - Pendant3735928559
?0xDEADBEEF
wird im Speicher als gespeichert0x30 0x78 0x44 0x45 0x41 0x44 0x42 0x45 0x45 0x46
.0xEFBEADDE
. Vielleicht das ein bisschen umformulieren. Ansonsten ist dies eine hervorragende Antwort - ich mag besonders die "Ansicht" -Analogie und die "Schielen" -Idee :)Aus C-Sicht wäre die Antwort "Wer weiß? Es ist undefiniertes Verhalten".
Typen sind ein C-Konzept, keine Hardware. Die C-Regeln gelten jedoch nicht, wenn Ihr Programm über undefiniertes Verhalten verfügt. Dies ist die wörtliche Bedeutung von undefiniertem Verhalten im C-Standard. Und Pufferüberläufe sind eine Form davon.
Ich schrieb anfangs "die C-Regeln gelten nicht mehr", aber tatsächlich ist das undefinierte Verhalten rückwirkend. C-Regeln gelten nicht für Programme, die in Zukunft ein undefiniertes Verhalten aufweisen werden.
quelle