Überschreitung der Feldgrenzen bei Arrays
-
Guten Morgen, guten Tag, guten Abend und gute Nacht! :p
Ich habe davon gelesen, dass der Compiler nicht überprüft, ob es das angesprochene Arrayelement gibt. Nun möchte ich einen Überlauf absichtlich erzeugen. Dazu habe ich folgenden Code geschrieben:
#include <stdio.h> int main(void) { int alpha[3]; /* Array mit 3 Elementen */ alpha[0] = 1; alpha[1] = 2; alpha[2] = 3; alpha[3] = 4; /* Dieses Element gibt es eigentlich nicht */ int k; /* Die Variablen k und l sollen den Speicherplatz von * alpha[3] überschreiben, weil alpha[3] eigentlich * keinen zugesicherten Speicherplatz besitzt. */ int l; k=15; l=16; printf ("%i\n", alpha[0]); /* 1 wird ausgegeben */ printf ("%i\n", alpha[1]); /* 2 wird ausgegeben */ printf ("%i\n", alpha[2]); /* 3 wird ausgegeben */ printf ("%i\n", alpha[3]); /* diese Ausgabe sollte ungleich 4 * sein. Ich erwarte den Wert von k oder l. Es wird aber trotzdem * die 4 ausgegeben!? */ printf ("%i\n", k); /* 15 wird ausgegeben */ printf ("%i\n", l); /* 16 wird ausgegeben */ return 0; }
Ist das Beispiel okay oder schon zu lang? Im letzten Kommentar steht meine Frage indirekt. Warum wird alpha[3] "korrekt" ausgegeben? Das Element gibt es doch gar nicht!?
Grüße
Tim
-
Da hast du halt Glück (oder Pech, wie man's nimmt) gehabt, es steht ja nirgends, dass irgendwas böses passieren muss. Bei mir wird da z.b. 15 ausgegeben.
-
Schade (wegen des Glücks, welches ich nun gar nicht will :)). Ich kompiliere mit dem GCC 4.4.3 und den Parametern "gcc -Wall -std=c99 -pedantic -c "%f" -Xlinker -Map=output.map". Kann es daran liegen?
-
Katzenstreu schrieb:
Ich kompiliere mit dem GCC 4.4.3 und den Parametern "gcc -Wall -std=c99 -pedantic -c "%f" -Xlinker -Map=output.map". Kann es daran liegen?
nee, C checkt niemals irgendwelche arraygrenzen ab. willst du 'nen absturz provozieren?
-
Ich wollte den Fehler sehen. Denn jetzt achte ich drauf und er tritt nicht auf. Später soll mir das nicht passieren, lieber dann jetzt. Aber warum gibt's keinen Fehler? Schreibt das Programm seine Daten nicht in einen Speicher von vorne nach hinten? Warum kann es gut gehen?
-
Warum kann es gut gehen?
Weil du scheinbar zufällig ein Byte erwischt hast, das in dem Fall nicht gebraucht wird. Aber du solltest ein seltsames Verhalten erzielen können, wenn du weiter darüber hinaus schreibst, irgendwann kommen da meistens irgendwelche Rücksprungadressen oder etwas ähnlich sensibles.
Ausgabe bei mir (gcc, win32):
1 2 3 4 15 16
-
Ausgabe bei mir (gcc, ubuntu 8.10, 32 bit):
1 2 3 16 15 16
-
Und das war beides die gleiche Kiste, und zwar keine virtuelle, sondern eine zum Angreifen. Du hast ein schönes kurzes Beispiel für einen nasal demon gepostet. Nur braucht man zum Testen halt mehrere Systeme.
-
Es klappt endlich. Es gibt Fehler und auch eine Fehlermeldung :).
#include <stdio.h> int main(void) { int alpha[3]; /* Array mit 3 Elementen */ alpha[0] = 1; alpha[1] = 2; alpha[2] = 3; alpha[3] = 4; /* Dieses Element gibt es eigentlich nicht */ alpha[4] = 5; alpha[5] = 6; alpha[6] = 7; alpha[7] = 8; alpha[8] = 9; alpha[9] = 10; alpha[10] = 11; alpha[11] = 12; alpha[12] = 13; int k; /* Die Variablen k und l sollen den Speicherplatz von * alpha[3] überschreiben, weil alpha[3] eigentlich * keinen zugesicherten Speicherplatz besitzt. */ int l; k=88888; l=44444; printf ("%i\n", alpha[0]); /* 1 wird ausgegeben */ printf ("%i\n", alpha[1]); /* 2 wird ausgegeben */ printf ("%i\n", alpha[2]); /* 3 wird ausgegeben */ printf ("%i\n", alpha[3]); /* diese Ausgabe sollte ungleich 4 * sein. Ich erwarte den Wert von k oder l. Es wird aber trotzdem * die 4 ausgegeben!? */ printf ("%i\n", alpha[4]); /* 5 wird nettweise ausgegeben */ printf ("%i\n", alpha[5]); /* 6 wird nettweise ausgegeben */ printf ("%i\n", alpha[6]); /* Endlich ein "Fehler", ein Überlauf. 44444 wird ausgegeben, die Variable l */ printf ("%i\n", alpha[7]); /* Auc hhier ein "Fehler". 88888 wird ausgegeben, die Variable k */ printf ("%i\n", alpha[8]); /* 9 wird ausgegeben, erstaunlicherweise korrekt */ printf ("%i\n", alpha[9]); /* 10 wird ausgegeben, erstaunlicherweise korrekt */ printf ("%i\n", alpha[10]); /* 11 wird ausgegeben, erstaunlicherweise korrekt */ printf ("%i\n", alpha[11]); /* 12 wird ausgegeben, erstaunlicherweise korrekt */ printf ("%i\n", alpha[12]); /* 13 wird ausgegeben, erstaunlicherweise korrekt */ printf ("%i\n", k); /* 15 wird ausgegeben */ printf ("%i\n", l); /* 16 wird ausgegeben */ /* Und dann wird noch "Segmentation fault" ausgegeben. Endlich * geschafft! */ return 0; }
Oder nur die Ausgabe:
1 2 3 4 5 6 44444 88888 9 10 11 12 13 88888 44444 Segmentation fault
Danke an euch beide! Nun ist's geklärt!
-
Katzenstreu schrieb:
Danke an euch beide!
dir haben 3 leute geantwortet.
-
Basher schrieb:
Katzenstreu schrieb:
Danke an euch beide!
dir haben 3 leute geantwortet.
Da lechzt er nach Anerkennung...
-
_matze schrieb:
Da lechzt er nach Anerkennung
nö, der OP könnte was übersehen haben.
-
Basher schrieb:
Katzenstreu schrieb:
Danke an euch beide!
dir haben 3 leute geantwortet.
Ich habe nur Beiträge von dir und µngbd gelesen. Oder gab's noch einen Verrückten, hilfsbereiten, Programmierer?
Mit _matze, der sich rein geschmuggelt hat, sind es nun 3
. Und noch mehr Anerkennung gilt es hier zu erreichen: C/C++ Forum :: ANSI C :: Einlesen von Array mit scanf() und dem &-Operator
-
Da lechzt er nach Anerkennung...
Hehe. Aber irgendwie muss er ja auch, nachdem auch die Signatur sehr nach Bashar aussieht. Mir macht das aber wenig aus, weil ich gewohnt bin, beide ernst zu nehmen.
-
Nun habe ich es auch gesehen. Nach 5 mal schauen. Basher und Bashar. Ihr seid wohl zwangsläufig ein Team :).
-
Und noch mehr Anerkennung gilt es hier zu erreichen: C/C++ Forum :: ANSI C :: Einlesen von Array mit scanf() und dem &-Operator
Ich hab's versucht. Jetzt würdest du mich in die Regierung wählen, oder?
-
Na klar µngbd . Aber zumindest dann musst du dich beim Bund ausweisen oder dich hier registrieren :). Warum bist du nicht registriert?
-
Katzenstreu schrieb:
Na klar µngbd . Aber zumindest dann musst du dich beim Bund ausweisen oder dich hier registrieren :). Warum bist du nicht registriert?
Frag Basher mal, warum er registriert ist...
-
Damit ihm niemand diesen genialen Namen wegnehmen kann. Stimmt's Basher?
-
Warum bist du nicht registriert?
Das bin ich, aber ich verwende den Account nur in den Foren, wo man als Unreg nicht schreiben darf.
Das hat mit Privatspähre zu tun, als Unreg können nur Marcus Bäckmann und die Moderatoren wissen, ob hinter "µngbd" immer der gleiche steckt. Und nach einigen Jahren hier vertraue ich ihnen in dem Zusammenhang. Ich mache aus "mngbd" (Account) meistens "µngbd" (Unreg). Kannst ja versuchen, herauszufinden, welche Accounts ich vorher hatte -- das geht, wenn man nur lange genug liest.
Wenn ich aber registriert wäre, dann könnte die ganze Welt wissen, daß ich immer der gleiche bin. Und wenn du einmal jemanden angelogen hast, von wegen: "ich muss arbeiten", derjenige aber deinen Usernamen kennt, und herausfindet, daß du gar nicht arbeitest, sondern die ganze Zeit hier herumstreitest -- dann kann das dein Privatleben belasten. Zu allem Überfluss kann man nach den Beiträgen registrierter User suchen, aber nach denen von Unregs nicht. Also verhindere ich so, daß sich jeder Protokolle über meine Aktivitäten hier anzeigen lassen kann.
Frag Basher mal, warum er registriert ist...
Ein kleiner Tip:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-249103-and-postdays-is-0-and-postorder-is-asc-and-start-is-20.html
-
Beispiel: hier steht alles, was du als Katzenstreu geschrieben hast:
http://www.c-plusplus.net/forum/search-var-search_author-is-Katzenstreu.html