Hallo Tom,
Ich versuche mir gerade C etwas näher zu bringen ...
das ist in unserem Metier nie ein Fehler. :-)
char *myfunc(void) {
char *output = "Output";
//strcat(output, arg);
return output;
}
Was macht diese Funktion? Sie legt einen String (also ein char-Array) als lokale Variable auf dem Stack an, und liefert einen Zeiger darauf zurück.
char *result = NULL;
result = myfunc();
printf("Ergebnis der Funktion: %s\n", result);
Folgt man der Argumentation im obigen Link, müsste doch ein Segmentation fault zu erwarten sein, da ja output ein lokaler Pointer ist und demnach nach Ausführung der Funktion vom Stack schon verschwunden sein muss.
Nein. "Verschwunden" ist erstmal nichts. Der Zeiger auf die auf dem Stack abgelegte Zeichenkette wird ja durch das return nach oben durchgereicht. Dann zeigt result also immer noch auf denselben Speicherbereich auf dem Stack wie der lokale Zeiger output innerhalb der Funktion. Da ein Programm ohne Einschränkung auf seinen eigenen Stack zugreifen darf, produziert das erstmal keinen Fehler.
Problematisch wird's allerdings, wenn nach der Rückkehr von myfunc() eine weitere Funktion aufgerufen wird. Die würde nämlich die noch auf dem Stack liegende Zeichenkette mit ihren eigenen lokalen Variablen überschreiben. Das Programm läuft dann zwar immer noch "fehlerfrei", aber deine Daten werden sich immer wieder auf unerklärliche Weise verändern.
char *string = "NAME,ORT,ALTER";
char *name; // soll enthalten NAME
char *ort; // soll enthalten ORT
char *alter; // soll enthalten ALTER
sscanf(string, "%s,%s,%s", name, ort, alter);
Hier ist nun so, dass die variable name dann gleich NAME,ORT,ALTER enthält. Wie ist das möglich?
Das ist mir auch schleierhaft. Denn *dieses* Beispiel müsste tatsächlich einen Segmentation Fault erzeugen. ;-)
Die oben deklarierten Zeiger name, ort, alter sind nicht initialisiert. Sie zeigen daher auf zufällige Speicherbereiche, und sscanf() kopiert dann Zeichen für Zeichen aus dem Eingabestring in die durch name, ort, alter referenzierten Bereiche - also buchstäblich "irgendwo" hin.
Ich würde aber grundsätzlich von der Verwendung der scanf-Funktionen abraten. Denn sie haben keine "eingebaute" Bereichsprüfung, können also nicht feststellen, ob der Puffer, auf den die übergebenen Zeiger vereisen, auch wirklich groß genug für das Ergebnis ist (bzw. ob es überhaupt ein gültiger Bereich ist). Funktionen, die eine Eingabe untersuchen und auswerten, schreibe ich mir lieber selbst - und zwar immer so, dass sie auch eine Bereichsüberprüfung vornehmen können oder alternativ die maximal zulässige Anzahl Zeichen von der aufrufenden Funktion übermittelt bekommen.
So long,
Martin
Der Bäcker schlägt die Fliegen tot
Und macht daraus Rosinenbrot.