Falscher Formatbezeichner in scanf("%d", unsigned short int) nach gets(Zeiger) ändert die char-Zeiger den Wert, aber warum?
Ich habe vor kurzem versucht, etwas C-Programmierung und stolperte über Folgendes problem. Ich bin mit NetBeans 7.4 64-IDE mit MinGW 32 Bit. Dies ist eine kurze Beispiel-code, die unterstreicht mein problem:
int main(void) {
unsigned short int temp;
char *pointer;
pointer = malloc(12 * sizeof(char));
printf("The pointers value is %d \n", (int)pointer);
printf("Type a short string:\n");
gets(pointer);
printf("The pointers value is %d \n", (int)pointer);
printf("Type an int: \n");
//This line changes the char pointer to an apparently random value
scanf("%d", &temp);
//Segmentation fault upon this point
printf("The pointers value is %d \n", (int)pointer);
//And here as well
free(pointer);
return (EXIT_SUCCESS);
}
Bis scanf alles in Ordnung ist. Der string gelesen wird, ist geschrieben in dem Speicher-Zeiger gerichtet ist. Aber NACH scanf verarbeitet wurde, pointer-Wert wird so geändert, dass der Zeiger zeigt auf jeden Raum. Also nicht nur mein string ist verloren, aber ich bekomme auch die Segmentierung Fehler beim Zugriff /freie memory, das gehört nicht zu meinem Programm.
Den Wert ändern, ist scheinbar zufällig. Jedes mal, wenn ich Debuggen das Programm, das den Mauszeiger verändert sich zu einem anderen Wert.
Habe ich bereits ableiten, dass die unsigned short int ist Schuld, oder eher die falsche Formatbezeichner ("%d statt %hu) in meinem scanf. Wenn ich ändern Sie entweder unsigned short int int "oder" %hu als Planer, funktioniert alles einwandfrei. So gibt es die Lösung.
Aber ich bin immer noch neugierig, warum und wie die Zeiger der betroffene durch diesen Fehler. Wer kann mir da helfen?
gets
. Es bietet keinen Schutz gegen einen buffer-overflow-Schwachstelle.InformationsquelleAutor clancy688 | 2013-11-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das Programm Undefiniertes Verhalten.
Müssen Sie sagen
scanf()
Sie, dass es nur Platz für eine kurze integer, wie sonst ist es zu wissen, welche Größe um die Nummer zu speichern, wie?Änderung:
Wo
h
bedeutet "halb", d.h.short
, undu
ist fürunsigned
. Ihr scheitern, um die richtige format-Konvertierung Planer verursacht Undefiniertes Verhalten, in denenscanf()
überschrieb eine benachbarte Variablen im Speicher.Beachten Sie bitte auch, dass
gets()
ist veraltet aufgrund der sehr gefährlich ist: bitte verwenden Sie es nicht. Verwenden Sie die viel mehr gut erzogenefgets()
statt. Und nie-Skala eine Zuordnung vonsizeof (char)
ist das nur eine sehr schwer zu lesende Art zu schreiben* 1
fügt keinen Wert.Ah, tut mir Leid für das nicht klarer. Ich habe jetzt editiert.
Beachten Sie, dass es nicht notwendig für die Verwendung von 'h' bei der übergabe eine kurze, printf, da die short wird nach int umgewandelt, wie es übergeben wird. für scanf, jedoch wird ein Zeiger übergeben, um die Lage zu schreiben; so muss die Funktion sein, genau gesagt, wie groß ein Wert zu schreiben.
InformationsquelleAutor unwind
Weil in C nichts hindert Sie daran, das schreiben über eine bestimmte variable Speicher. Alles ist nur eine Adresse, zu wissen, wie viele bytes nach dieser Adresse können Sie schreiben, ist bis zu Ihnen, und nicht etwas, was der compiler überprüfen.
einen short int verbraucht weniger bytes des Arbeitsspeichers als ein normales int. Sie stellte einen kurzen int. Dann fragte Sie scanf schreiben eine normale int. scanf schrieb über den zugewiesenen Arbeitsspeicher, und überschrieb Teil von char * - pointer, die passiert zu sein, nur nach Ihrem kurzen int. Dies nennt man Undefiniertes Verhalten, weil man nicht weiß, was konnte Sie überschrieben werden. Die Tatsache, dass der Zeiger befindet sich im Speicher direkt nach temp ist ein Zufall.
Zeiger zeigt nun auf einen ungültigen Speicher-Adresse, und Sie erhalten einen segmentation fault, wenn Sie versuchen, darauf zuzugreifen.
Eines Zeigers ist eigentlich nur ein weiterer integer-variable (eine lange), die speichert eine Speicheradresse.
Nicht die Größe eines Zeigers variieren zwischen den Plattformen?
Tut es, wie die Größe eines long. Ein Zeiger wäre die gleiche Größe wie die Speicher-Adresse, die Größe des CPU (also 64 bits für einen 64-bit-CPU). In der Regel eine lange, ist die gleiche Größe, da ein langer ist die gleiche Größe wie die "native" integer-Datentyp der CPU. In der Regel.
InformationsquelleAutor phenompbg