2016-05-19 8 views
1

Ich verwende C auf einer 32-Bit-Architektur. Wenn ich array[-2147483635] verwende, warum übersetzt C es in array[13]?Integer-Überlauf auf Array-Index

-2147483635 auf Complement Twos ist 10000000000000000000000000001101b

Ist es das linke Bit nehmen und es auf 0 zu übersetzen, so dass es 00000000000000000000000000001101b wird, das heißt 13 ???

Ich glaube nicht, dass es zu size_t geworfen wird. Weil size_t-2147483635 zu 4294967264 übersetzt.

+0

Warum glaubst du, es übersetzt "zu Array [13]"? – jotik

+0

Ich sehe Hexe Adresse es schreiben – jordan

+0

Was ist der Typ von 'Array'? – jotik

Antwort

6

Es wird nicht in array[13] übersetzt, aber richtig zu array[-2147483635]. Dies kann jedoch immer noch zu undefiniertem Verhalten führen. Zum Beispiel auf 32-Bit-x86, die Montage für

char f(char * a) { return a[-2147483635]; } 
int g(int * a) { return a[-2147483635]; } 

könnte wie folgt aussehen:

f: 
    pushl %ebp 
    movl %esp, %ebp 
    movl 8(%ebp), %eax 
    movzbl -2147483635(%eax), %eax 
    popl %ebp 
    ret 
g: 
    pushl %ebp 
    movl %esp, %ebp 
    movl 8(%ebp), %eax 
    movl 52(%eax), %eax 
    popl %ebp 
    ret 

Online Beispiel here See. So sieht alles gut für das Array char, aber Sie können den Überlauf für das Integer-Array (movl 52(%eax), %eax wo 52 ist 4 × 13) sehen. Dies wird durch das nicht definierte Verhalten verursacht, da das Element mit dem Index -2147483635 auf 32-Bit-Systemen möglicherweise nicht für ein Array oder einen Zeiger existieren kann. Für Arrays würde auf ein Element vor dem ersten Element des Arrays zeigen, daher undefiniertes Verhalten. Für jeden Zeiger, wenn Sie nur maximal 2 oder 4294967296 Bytes Speicher haben und sagen wir, dass array auf das letzte Byte bei Index 2 -1 oder 4294967295 zeigt, dann würde das -2147483635-te Element müssen sich an der Speicheradresse befinden, die 4294967295 - 8589934540 ist, die -4294967245 ist. Eine solche Speicheradresse macht keinen Sinn.

Siehe cppreference oder die C-Norm in § 6.5.6 (8) für Details.

+0

so kann ich nicht wissen, wicth type das minus speichern? Wenn es size_t oder unsigned int? und warum habe ich Integer-Überlauf bekommen? weil ich Minus auf Index gesetzt habe? also muss es in plus übersetzen? – jordan

+0

@jordan Ich habe meine Antwort in Bezug auf Ihre Kommentare zu der Frage – jotik

3

-2147483635 passt gut in den Bereich einer 4-Byte-Ganzzahl mit Vorzeichen, da die untere Grenze –2147483648 ist.

Subskribierung von Arrays mit negativen Indizes ist ein nicht definiertes Verhalten, da es sich um den Zugriff auf Speicher handelt, der außerhalb seiner Grenzen liegt. Nur wenn array tatsächlich ein Zeiger ist und über das 2147483635 * sizeof(int) Byte einer ausreichend großen zusammenhängend zugeordneten Speicherregion hinausweist, können Sie diesen negativen Index verwenden.

+0

ausgiebig verbessert, warum also 13? wegen undefiniertem Verhalten? es richtig zu sagen, dass das linke Bit 0 wird? – jordan

+1

@jordan: Veröffentlichen Sie den genauen Code, den Sie kompilieren. Außerdem, wie können Sie sicher sein, dass der Index zu "13" auswertet? –

+0

ich sicher, dass 13, weil ich die pleace es schreiben schreiben ist es unpassierbar, dass es dauert, um links zu setzen und dort 0 setzen? – jordan

Verwandte Themen