Ich habe also einen C-Code:
%Vor%Dies kompiliert, läuft und verhält sich so, wie es aussieht. Wenn jedoch einer oder beide Zeichenzeiger als globale Variable deklariert sind, führt strcpy zu einem Segmentierungsfehler. Warum passiert das? Offensichtlich gibt es einen Fehler in meinem Verständnis von Umfang.
Wie andere Poster erwähnt haben, liegt die Ursache des Problems darin, dass temp nicht initialisiert ist. Wenn es auf dem Stapel als automatische Variable deklariert wird, enthält es den Müll, der sich an diesem Speicherort befindet. Anscheinend ist für den Compiler + CPU + OS, den Sie ausführen, der Müll an dieser Stelle ein gültiger Zeiger. Der strcpy "ist erfolgreich", da er nicht segfault ist, aber tatsächlich hat er einen String an eine beliebige Stelle irgendwo im Speicher kopiert. Diese Art von Speicherkorruptionsproblemen bringt überall Angst in die Herzen von C-Programmierern, da es außerordentlich schwierig zu debuggen ist.
Wenn Sie die temp-Variablendeklaration in den globalen Bereich verschieben, wird sie in den BSS-Abschnitt eingefügt und automatisch auf Null gesetzt. Versuche, * temperature zu dereferenzieren, führen dann zu einem segfault.
Wenn Sie * den Pfad zum globalen Bereich verschieben, bewegt sich * temp um eine Position auf dem Stapel nach oben. Der Müll an diesem Ort ist anscheinend kein gültiger Zeiger und daher führt Dereferenzierung * temp zu einem segfault.
Die temporäre Variable zeigt nicht auf Speicher (Speicher) und ist nicht initialisiert.
Wenn temp als char temp[32];
deklariert wird, dann würde der Code funktionieren, egal wo er deklariert ist. Es gibt jedoch andere Probleme mit der Deklaration von Temp mit einer festen Größe wie dieser, aber das ist eine Frage für einen anderen Tag.
Nun, warum stürzt es ab, wenn es global und nicht lokal deklariert wird. Glück ...
Wenn es lokal deklariert wird, kommt der Wert von temp von dem Wert, der sich zu diesem Zeitpunkt auf dem Stack befinden könnte. Es ist Glück, dass es auf eine Adresse zeigt, die keinen Absturz verursacht. Es wird jedoch Speicher gelöscht, der von jemand anderem verwendet wird.
Wenn global deklariert, werden diese Variablen in den meisten Prozessoren in Datensegmenten gespeichert, die Seiten mit Bedarf null verwenden. Daher erscheint char *temp
so, als wäre char *temp=0
deklariert worden.
Wie oben erwähnt, haben Sie vergessen, Speicherplatz für temp.
Ich bevorzuge strdup
bis malloc+strcpy
. Es macht was du willst.
Nein - das funktioniert nicht unabhängig von den Variablen - es sieht einfach so aus, als hättest du (un) Glück gehabt. Sie müssen Speicherplatz reservieren, um den Inhalt der Zeichenfolge zu speichern, anstatt die Variable nicht initialisiert zu lassen.
Nichtinitialisierte Variablen auf dem Stapel zeigen auf ziemlich zufällige Speicherorte. Wenn diese Adressen gültig sind, trampelt dein Code überall herum, aber es wird kein Fehler angezeigt (aber es kann zu Fehlern in der Speicherbeschädigung kommen, die anderswo in deinem Code auftreten).
Globale Fehler schlagen regelmäßig fehl, da sie normalerweise auf bestimmte Muster festgelegt werden, die auf nicht zugeordneten Speicher verweisen. Wenn Sie versuchen, diese zu dereferenzieren, erhalten Sie sofort einen segfault (was besser ist - wenn Sie es später lassen, wird es sehr schwer, den Fehler zu finden).
Der wichtige zu beachtende Teil:
Zielzeichenfolge dest muss groß genug sein, um die Kopie zu erhalten.
In Ihrer Situation hat temp keinen Speicher zum Kopieren in.
Von der man-Seite von strcpy kopiert:
%Vor% Sie rufen ein undefiniertes Verhalten auf, da Sie die Variable temp
nicht initialisieren. Es zeigt auf einen zufälligen Speicherort im Speicher, so dass Ihr Programm funktioniert , aber höchstwahrscheinlich wird es segfault. Die Zielzeichenfolge muss ein Array sein oder auf dynamischen Speicher verweisen:
Verwenden Sie außerdem strncpy()
anstelle von strcpy()
, um Pufferüberläufe zu vermeiden.
Tags und Links c scope pointers segmentation-fault character