Frage

Also ich habe etwas C-Code:

#include <stdio.h>
#include <string.h>

/* putting one of the "char*"s here causes a segfault */
void main() {
  char* path = "/temp";
  char* temp;
  strcpy(temp, path);
}

Dies wird kompiliert, ausgeführt 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 liegt ein Fehler in meinem Verständnis des Umfangs vor.

War es hilfreich?

Lösung

Wie andere Plakate erwähnt, ist die Wurzel des Problems ist, dass Temp nicht initialisiert ist. Wenn sie als eine automatische Variable auf dem Stapel deklariert es enthält, was Müll in dieser Speicherstelle passiert zu sein. Offenbar für den Compiler + CPU + OS Sie ausgeführt werden, der Müll an dieser Stelle ist ein gültiger Zeiger. Die strcpy „gelingt“, dass es nicht segfault, aber es kopiert eine Zeichenkette in einer beliebigen Position an anderer Stelle im Speicher wirklich. Diese Art von Speicher Korruption Problem Streiks Angst in die Herzen des C-Programmierers überall, wie es zu debuggen außerordentlich schwierig ist.

Wenn Sie die temporäre Variablendeklaration zu globalem Bereich bewegen, wird es in dem BSS Abschnitt platziert und automatisch auf Null gesetzt. Versuch zu dereferenzieren * Temp dann in einem segfault zur Folge hat.

Wenn Sie sich bewegen * Weg zum globalen Bereich, dann * Temp bewegt einen Standort auf dem Stack. Der Müll an dieser Stelle ist offenbar kein gültiger Zeiger, und so dereferencing * Temp Ergebnisse in einem segfault.

Andere Tipps

Die Temperatur Variable verweist nicht auf jeden Speicher (Speicher) und es ist nicht initialisiert.

, wenn Temp als char temp[32]; deklariert wird dann der Code würde funktionieren, egal, wo sie deklariert ist. Allerdings gibt es andere Probleme mit erklärte Temp mit einer festen Größe so, aber das ist eine Frage für einen anderen Tag.

Nun, warum nicht abstürzen es, wenn global und nicht lokal deklariert. Luck ...

Wenn lokal deklariert, wird der Wert der Temperatur kommt von was auch immer Wert auf dem Stapel sein könnte zu diesem Zeitpunkt. Es ist Glück, dass es zu einer Adresse verweist, die nicht einen Absturz verursacht. Es wird jedoch Speicher von jemandem benutzt Wegwerfen anderes.

Als global deklariert, auf den meisten Prozessoren werden diese Variablen in Datensegmente gespeichert werden, die Nachfrage Null-Seiten verwenden. So char *temp scheint, als ob es char *temp=0 erklärt wurde.

Sie haben vergessen, zuzuordnen und initialisieren Temperatur:

temp = (char *)malloc(TEMP_SIZE);

So stellen Sie sicher TEMP_SIZE groß genug ist. Sie können dies auch zur Laufzeit berechnen, dann stellen Sie sicher, dass die Größe genug ist (mindestens strlen (Pfad) werden)

Wie oben erwähnt, vergessen Sie Raum für temporäre zuzuordnen. Ich ziehe strdup malloc+strcpy. Es tut, was Sie tun möchten.

Nein - das funktioniert nicht unabhängig von dem Variablen - es sieht aus wie es tat, weil du hast (un) glücklich. Sie müssen Speicherplatz zuweisen, den Inhalt der Zeichenfolge zu speichern, anstatt verlassen die Variable uninitialised.

Uninitialised Variablen auf dem Stapel geht bei so ziemlich zufälligen Orten der Erinnerung zu zeigen. Wenn diese Adressen gültig sein passieren, Ihr Code überall mit Füßen treten, was auch immer es war, aber Sie werden nicht einen Fehler (können aber auch böse Speicherfehler Fehler im Zusammenhang mit einem anderen Stelle im Code erhalten).

Globals konsequent scheitern, weil sie in der Regel auf bestimmte Muster fertig, die nicht zugeordneten Speicher zeigen. Der Versuch, dereferenzieren diese Ihnen einen segfault gibt sofort. (Was besser ist - so dass es später auf den Fehler sehr schwer aufzuspüren macht)

Ich möchte zunächst Adams Fragment umschreiben als

// Make temp a static array of 256 chars
char temp[256];
strncpy(temp, sizeof(temp), path);
temp[sizeof(temp)-1] = '\0';

So können Sie:

1. don't have magic numbers laced through the code, and
2. you guarantee that your string is null terminated.

Der zweite Punkt ist bei dem Verlust der letzten Zeichen der Quellzeichenfolge, wenn es> = 256 Zeichen lang sein.

Der wichtige Teil, den Sie beachten sollten:
Die Zielzeichenfolge dest muss groß genug sein, um die Kopie zu empfangen.
In Ihrer Situation ist temp kein Speicher zum Kopieren zugewiesen.

Von der Manpage von strcpy kopiert:

DESCRIPTION
   The  strcpy()  function  copies the string pointed to by src (including
   the terminating '\0' character) to the array pointed to by  dest.   The
   strings  may not overlap, and the destination string dest must be large
   enough to receive the copy.

Sie den Aufruf nicht definiertes Verhalten, da Sie nicht die temp Variable initialisiert. Er verweist auf einen zufälligen Ort im Speicher, so dass Ihr Programm kann Arbeit, aber höchstwahrscheinlich wird es segfault. Sie müssen Ihre Zielstring haben ein Array sein, oder haben es zu dynamischen Speicher zeigen:

// Make temp a static array of 256 chars
char temp[256];
strncpy(temp, 256, path);

// Or, use dynamic memory
char *temp = (char *)malloc(256);
strncpy(temp, 256, path);

Verwenden Sie auch strncpy() statt strcpy() Pufferüberschreitungen zu vermeiden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top