2016-08-22 2 views
0

Das folgende Codebeispiel Verhalten ist nicht definiert ..undefinierte Verhalten von std :: string, wenn c_str() verwendet

char * getName() 
{ 
    std::string name("ABCXYZ"); 
    return name.c_str(); 
} 

Dies liegt daran, Name den Gültigkeitsbereich verlässt. Aber ich wollte verstehen, wie es anders ist, wenn wir eine std :: string zurückgeben und nicht undefiniertes Verhalten erzeugen?

+1

Wenn Sie es (den 'std :: string') nach Wert zurückgeben, wird es kopiert/verschoben, also ist es nicht UB. – tkausl

+0

Die Rückgabe einer 'std :: string 'würde aller Wahrscheinlichkeit nach nichts kopieren; Der Rückgabewert wird nach Möglichkeit an Ort und Stelle erstellt. C++ 17 garantiert das sogar manchmal. Wenn das nicht möglich ist, wird die Zeichenfolge zumindest ausgezogen anstatt kopiert. Es gibt wirklich nicht viel zu befürchten. – chris

+1

Es ist eine wohlbekannte C++ - Richtlinie, dass Sie lokale Objekte niemals durch Referenz (oder Zeiger) zurückgeben sollten. Sie können mehr darüber in Effective C++ lesen, aber die Erklärung von David Schwartz deckt das meiste davon ab. –

Antwort

1

Einfach weil zurück Anweisung kopiert oder bewegt (siehe C++ 11) das Objekt zurückgegeben.

Mit diesem Code:

std::string getName() { 
    std::string name("ABCXYZ"); 
    return name; 
} 

der String Name wird dem Anrufer kopiert und zurückgeführt.

mit Ihrem Code, Rückkehr wird eine Kopie eines Zeiger machen (weil Ihre Funktion einen Zeiger zurückgibt), nicht von dem spitzen Gegenstand. Das wird ein UB produzieren.

+0

Könnte kopiert werden. Moderne Compiler verfügen über einen großen Pool an Tricks, um das Kopieren von Daten zu vermeiden. Pop "Return Value Optimization" und "Copy Elision" in die Web-Suche Ihrer Wahl, wenn Sie mehr über zwei der gängigsten Tricks erfahren möchten. – user4581301

+0

@ user4581301 Ich kenne diese "Tricks" sehr gut. Ich habe sie nicht erwähnt, weil OT. Egal, was ich gesagt habe, es betrifft nur Standard, lasst uns plattformabhängige Aspekte sehen ;-) –

5

Wenn Sie einen return Wert eingeben, wird der Wert sicher an den Aufrufer zurückgegeben. Das ist, was die return Anweisung tut.

In dem Fall, in dem Sie c_str aufrufen, ist der Wert, den Sie zurückgeben, ein Zeiger in der Zeichenfolge. Sobald die Zeichenfolge zerstört ist, zeigt dieser Zeiger jetzt auf nichts. Der Wert ist sicher zurückgegeben, es ist nur, dass Sie nichts damit sicher tun können.

Der Wert einer string ist der Inhalt der Zeichenfolge. In diesem Fall wird der Inhalt der Zeichenfolge an den Aufrufer übergeben. Man könnte sagen, dass der primäre Zweck der Klasse std::string darin besteht, ein Objekt bereitzustellen, dessen Wert der Inhalt einer Zeichenkette ist.

Verwandte Themen