2016-07-01 14 views
1

Ich habe einen einfachen Code.String von einer C-Funktion zurückgeben

#define MY_STRING "String example" 

char* string_return_function() 
{ 
    return MY_STRING; 
} 

Der obige Code funktioniert, aber ich bin mir nicht sicher, wie. Ich denke, die string_return_function() gibt eine lokale Adresse zurück, die freigegeben wird, sobald die Funktion beendet wird.

Antwort

6

Nein, so funktioniert es nicht.

Zeichenfolgenliterale werden im Speicher gespeichert, die so lange bestehen bleiben, wie das Programm ausgeführt wird. Daher gibt die Funktion nur einen Zeiger auf die Zeichenfolgenkonstante zurück.

Zur Laufzeit findet keine String-Erstellung/Initialisierung statt, es werden keine Zeichen kopiert. Es gibt nur einen Zeiger zurück, der Maschinencode der Funktion ist wahrscheinlich nur ein paar Anweisungen.

Zum Beispiel, hier ist die (aufgeräumte) x86 Code, den ich von https://assembly.ynh.io/ bekam:

string_return_function: 
    movl $.LC0, %eax 
    ret 

Wo .LC0 ist einfach ein Ort, um die Zeichenfolge zu halten. Also, das sind 2 Anweisungen einschließlich der Rückkehr von Functin Overhead/Boilerplate. Ziemlich effizient. :)

Sie dieses Denkens:

char * bad_code(void) 
{ 
    char response[] = MY_STRING; 
    return response; 
} 

Dies ist fehlerhaftem Code da es ein lokales Array zurückgibt. Es spielt keine Rolle, dass das in Frage stehende Array aus dem Literal initialisiert wird, das ist nicht, was zurückgegeben wird.

Benennen Sie auch nicht Ihre Funktion beginnend mit str, alle diese Namen sind reserviert; der C11 Entwurf sagt:

Funktionsnamen, die mit str, mem oder wcs und ein Klein Buchstaben beginnen können zu den Erklärungen im <string.h> Header hinzugefügt werden.

+0

Verdammt, ich bin nicht mehr die schnellste Waffe im Westen :( – Lundin

+0

Danke @unwind! Könnten Sie bitte weitere Informationen über diesen persistenten Speicher geben? Ist es Heap- oder Stack-Speicher? – MayurK

+0

Können Sie bitte erklären letzter Satz? Gibt es eine Standardreferenz oder nur eine Konvention? – deniss

2

Stringliterale werden in statischen Nur-Lese-Speicher zugeordnet, in der Regel .rodata (Nur-Lese-Daten) genannt. Sie bleiben während der gesamten Lebensdauer Ihres Programms bestehen, so dass Sie einen Zeiger auf eins zurückgeben können.

Hätten Sie jedoch die Stringliteral in einen temporären Stapel Variable kopiert, würde der Code nicht sicher sein und nicht definiertes Verhalten aufrufen:

char* string_return_function() 
{ 
    char mystring [] = "String example"; 
    return mystring; // BAD 
} 
+0

Es besteht keine Anforderung, dass der Speicherbereich schreibgeschützt ist.'const 'und String-Literale sind nicht änderbar vor allem eine Garantie für den Programmierer. – Olaf

1

Stringliterale in einer Reihe von char mit statischer Speicherdauer führen.

Zum Beispiel kann der Standard-1999 C, Abschnitt 6.4.5, para 5 beginnt mit

Übersetzungsphase In 7 wird ein Byte-Code oder der Wert Null wird an jede Mehrbyte-Zeichenfolge angehängt, die von einem Ergebnis string literal oder literals.65) Die Multibyte-Zeichenfolge wird dann verwendet, um ein Array von statischer Speicherdauer und -länge zu initialisieren, das gerade ausreicht, um die Sequenz zu enthalten.

Die statische Speicherdauer bedeutet, dass die Anordnung, die die Stringliteral fortgesetzt, nachdem die Funktion string_return_function() kehrt zu existieren.