Die Dokumentation ist korrekt. Verwenden c_str()
Sie diese Option, wenn Sie eine nullterminierte Zeichenfolge möchten.
Wenn die Implementierer data()
in Bezug auf die Implementierung zufrieden c_str()
waren, müssen Sie sich keine Sorgen machen. Verwenden data()
Sie diese Option dennoch, wenn die Zeichenfolge nicht nullterminiert werden muss. In einigen Implementierungen kann sich herausstellen, dass sie eine bessere Leistung als c_str () aufweist.
Zeichenfolgen müssen nicht unbedingt aus Zeichendaten bestehen, sondern können aus Elementen eines beliebigen Typs bestehen. In diesen Fällen data()
ist sinnvoller. c_str()
Meiner Meinung nach ist es nur dann wirklich nützlich, wenn die Elemente Ihrer Zeichenfolge zeichenbasiert sind.
Extra : Ab C ++ 11 müssen beide Funktionen identisch sein. dh muss data
jetzt nullterminiert werden. Laut cppreference : "Das zurückgegebene Array ist nullterminiert, dh data () und c_str () führen dieselbe Funktion aus."
.data()
konstante Überladung für , sodass sie für nicht konstante Zeichenfolgen nicht mehr gleichwertig sind.In C ++ 11 / C ++ 0x ,
data()
undc_str()
ist nicht mehr anders. Und daherdata()
muss am Ende auch eine Null-Kündigung erfolgen.quelle
std::string
ein Extra zugewiesen wird . Wenn Sie dies tun , werden beide und garantiert auf 0 ausgewertet.char
'\0'
std::string s("\0");
s.data()[0]
s.data()[1]
Selbst wenn Sie wissen, dass sie dasselbe tun oder dass .data () .c_str () aufruft, ist es nicht richtig anzunehmen, dass dies bei anderen Compilern der Fall ist. Es ist auch möglich, dass sich Ihr Compiler mit einer zukünftigen Version ändert.
2 Gründe für die Verwendung von std :: string:
std :: string kann sowohl für Text als auch für beliebige Binärdaten verwendet werden.
Sie sollten die Methode .c_str () verwenden, wenn Sie Ihre Zeichenfolge als Beispiel 1 verwenden.
Sie sollten die .data () -Methode verwenden, wenn Sie Ihre Zeichenfolge als Beispiel 2 verwenden. Nicht, weil die Verwendung von .c_str () in diesen Fällen gefährlich ist, sondern weil es expliziter ist, dass Sie mit Binärdaten für andere Überprüfungen arbeiten dein Code.
Mögliche Gefahr bei der Verwendung von .data ()
Der folgende Code ist falsch und kann einen Segfault in Ihrem Programm verursachen:
Warum ist es für Implementierer üblich, dass .data () und .c_str () dasselbe tun?
Weil es effizienter ist. Die einzige Möglichkeit, .data () dazu zu bringen, etwas zurückzugeben, das nicht nullterminiert ist, besteht darin, .c_str () oder .data () ihren internen Puffer kopieren zu lassen oder nur 2 Puffer zu verwenden. Ein einzelner nullterminierter Puffer bedeutet immer, dass Sie bei der Implementierung von std :: string immer nur einen internen Puffer verwenden können.
quelle
Es wurden bereits einige Anmerkungen zum Zweck beantwortet: Umsetzungsfreiheit.
std::string
Operationen - z. B. Iteration, Verkettung und Elementmutation - benötigen keinen Nullterminator. Wenn Sie das nichtstring
an eine Funktion übergeben, die eine nullterminierte Zeichenfolge erwartet, kann es weggelassen werden.Dies würde es einer Implementierung ermöglichen, dass Teilzeichenfolgen die tatsächlichen Zeichenfolgendaten gemeinsam nutzen: Sie
string::substr
könnten intern einen Verweis auf gemeinsam genutzte Zeichenfolgendaten und den Start- / Endbereich enthalten, wodurch das Kopieren (und die zusätzliche Zuordnung) der tatsächlichen Zeichenfolgendaten vermieden wird. Die Implementierung würde die Kopie verschieben, bis Sie c_str aufrufen oder eine der Zeichenfolgen ändern. Es würde niemals eine Kopie angefertigt werden, wenn die beteiligten Strigns nur gelesen würden.(Copy-on-Write-Implementierung macht in Multithread-Umgebungen nicht viel Spaß, und die typischen Speicher- / Zuordnungsersparnisse sind den komplexeren Code heutzutage nicht wert, sodass sie selten durchgeführt werden.)
Ebenso
string::data
erlaubt eine andere interne Darstellung, zB ein Seil (verknüpfte Liste von Stringsegmenten). Dies kann die Einfüge- / Ersetzungsvorgänge erheblich verbessern. Auch hier müsste die Liste der Segmente beim Aufrufen vonc_str
oder auf ein einzelnes Segment reduziert werdendata
.quelle
Zitat aus
ANSI ISO IEC 14882 2003
(C ++ 03 Standard):quelle
Alle vorherigen Commements sind konsistent, aber ich möchte auch hinzufügen, dass str.data () ab c ++ 17 ein char * anstelle von const char * zurückgibt
quelle
const
undnon-const
Überladungen sind seit C ++ 17 verfügbar.