2012-07-04 4 views
5

Ich schreibe eine String-Klasse, die std :: string für eine Hausaufgabe ähnlich ist, aber ich kann nicht herausfinden, wie man einen C-String zurückgibt, der kein Speicherleck verursacht und bleibt bis dahin dasselbe wird nicht mehr verwendet. Ich habe derzeit:Wie gibt std :: string :: c_str() eine C-Zeichenfolge zurück, die keinen Speicherverlust oder undefinierten C-String-Inhalt verursacht?

const char* string::c_str() 
{ 
    char c[_size+1]; 
    strncpy(c,_data,_size); 
    c[_size]='\0'; 
    return c; 
} 

aber die Inhalte werden kurz nach dem Aufruf außer Kraft gesetzt. Wenn ich dynamische Zuordnung mache, habe ich entweder ein Speicherleck oder nur eine C-Zeichenfolge kann von einer gegebenen Zeichenfolge jederzeit existieren. Wie kann ich das vermeiden?

+1

"* oder nur ein C-String kann jederzeit aus einem gegebenen String bestehen *" So funktioniert 'std :: string" - was ist das Problem? – ildjarn

+0

Wenn 'strncpy()' die Antwort ist, hast du wahrscheinlich [die falsche Frage] (http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not- safer-strcpy.html). –

+0

Ich wusste nicht, dass es nur existieren musste, bis es geändert wurde. Es funktioniert jetzt in O (1) Zeit. –

Antwort

7

Aber die Zeichenfolge, auf die c_str zeigt, ist nur gut definiert, bis die std::string als nächstes modifiziert (oder zerstört) wird.

Eine Möglichkeit, dies zu erreichen, besteht darin, einfach einen Zeiger auf Ihren internen Puffer zurückzugeben (vorausgesetzt, er ist null-terminiert). Beachten Sie, dass ein normkonformes c_str in O (1) -Zeit arbeiten muss; Kopieren ist also nicht erlaubt.

+1

Gut zu wissen. Das ist fast so, als würde man eine bestimmte Implementierung der Klasse "std :: string" erzwingen, nämlich als ein Array von Zeichen. – alfC

4

Von http://www.cplusplus.com/reference/string/string/c_str/:

zurückgegebenen Array verweist auf eine interne Position mit den erforderlichen Speicherplatz für diese Folge von Zeichen plus seinen Abschluß null-Charakter, aber die Werten in dieser Matrix sollte nicht geändert werden in das Programm und sind nur garantiert unverändert bis zum nächsten Aufruf an eine nicht-konstante Member-Funktion des String-Objekts.

0

Der von c_str() zurückgegebene Puffer ist nicht garantiert, dass er gleich bleibt oder sogar gültig ist, bis er nicht mehr verwendet wird.

Es ist nur garantiert gültig zu bleiben, bis die std :: string in irgendeiner Weise geändert wird.

Die Implementierung ist einfach: Halten Sie die interne Repräsentation des Strings immer null-terminiert und geben Sie einen Zeiger auf die interne Repräsentation von c_str() zurück.

Verwandte Themen