2016-07-25 14 views
6

Ich bin etwas verwirrt über die folgenden C++ Code:Initialisierung einer statischen const variable

#include <iostream> 

using namespace std; 

void test(const string& str) 
{ 
    static const char * const c = str.c_str(); 
    cout << c << endl; 
} 

int main(int argc, char* argv[]) 
{ 
    test("Hello"); 
    test("Nooo"); 
    return 0; 
} 

Da die Variable c als static deklariert und const, sollte dies nicht nur einmal initialisiert werden und halten seinen Anfangswert bis der Prozess abgeschlossen ist? Nach dieser Argumentation, erwartete ich die folgende Ausgabe:

Hello 
Hello 

Aber ich habe:

Hello 
Nooo 

Können Sie den Wert der Variablen c klären, warum wenn es zwischen zwei Funktionsaufrufe sogar modifiziert wurde, ist eine const Variable?

Antwort

14

Ihr Programm hat undefiniertes Verhalten.

Wenn Sie passieren zu "hello"test, ein temporären std::string Objekt erzeugt, und von diesem String c ist konstruiert (die nur ein Zeiger auf die Daten des String-Objekts ist).

Wenn der Funktionsaufruf beendet wird, wird das temporäre std::string Objekt zerstört und c wird zu einem ungeeigneten Zeiger. Wenn Sie es erneut verwenden, ist das Verhalten nicht definiert.

In Ihrem Fall hat das zweite temporäre Objekt std::string die exakt gleiche Speicheradresse wie die erste, also zeigt c auf diese Daten. Dies ist nicht garantiert.

+0

Eigentlich ist es nicht undefiniert. ** Dereferenzieren ** ist nicht definiert. Da es immer eine gültige Adresse hat, wenn dereferenziert wird, ist es ein gültiges Programm. – StoryTeller

+3

@StoryTeller, 'cout << c << endl;' dereferenziert den Zeiger. –

+1

@StoryTeller Der Ausgabeoperator verwendet Dereferenzierung. –

1

Sie haben undefiniertes Verhalten in Ihrem Code, so dass diese Ergebnisse variieren können. Die UB ist, weil Anruf test("Hello"); ein temporäres erzeugt, das Sie dann statischer lokaler Variable zuweisen. Dieses temporäre Objekt wird nach dem Ende eines Aufrufs gelöscht, daher hängt der Zeiger in der Testfunktion. Wenn Sie es verwenden, haben Sie ein undefiniertes Verhalten.

Es ist möglich, dass der Speichermanager denselben Speicherbereich wieder verwendet, sodass in den Ergebnissen Hello und Nooo angezeigt werden.

Verwandte Themen