2012-04-04 18 views
45

jest następujący kod C++ dobrze wykształcona:std :: string :: c_str() i uzupełnienia tymczasowe

void consumer(char const* p) 
{ 
    std::printf("%s", p); 
} 

std::string random_string_generator() 
{ 
    // returns a random std::string object 
} 

consumer(random_string_generator().c_str()); 

Problem mam z nim jest to, że po utworzeniu tymczasowego obiektu std :: string i biorąc wskaźnik c_str(), nic nie zapobiega zniszczeniu obiektu std :: string (a może się mylę?). Czy możesz wskazać mi standard, jeśli mimo wszystko kod jest OK. Działa, gdy testuję za pomocą g ++.

Odpowiedz

56

Wskaźnik zwrócony przez std::string::c_str() punktów do pamięci utrzymywanego przez obiekt strun. Zachowuje ważność do czasu wywołania niestanowiącej funkcji w obiekcie typu string lub do zniszczenia obiektu tekstowego . Obiekt tekstowy, o który się martwisz, jest tymczasowy. Zostanie zniszczony na końcu pełnego wyrażenia, a nie przed i , nie po. W twoim przypadku koniec pełnego wyrażenia następuje po wywołaniu do consumer, więc twój kod jest bezpieczny. Nie byłoby, gdyby gdzieś zapisał gdzieś wskaźnik, z pomysłem użycia go później.

Żywotność tymczasowych została ściśle zdefiniowana od C++ 98. Zanim to się zmieniło, zależało od kompilatora, a kod, który napisałeś , nie działałby z g ++ (przed 1995, około — g ++ zmienił to niemal natychmiast, gdy komitet standardów głosował nad nim). (Wtedy też nie było std::string, ale te same problemy dotyczą dowolnej napisanej przez użytkownika klasy ciągów znaków.)

18

Tymczasowa std::string „s życia rozciąga się tuż za punktem, gdzie consumer powraca, więc jest bezpieczny w użyciu niczego na ten ciąg znaków bezpośrednio z consumer. Co to jest , a nie OK, to zapisanie wartości, którą zwraca c_str i próba użycia jej później (tymczasowy zostanie zniszczony, a my możemy tylko zgadywać, co znajdziesz na drugim końcu wskaźnika).

+1

Czy możesz podać wskazówkę dotyczącą standardu C++ 03 lub C++ 11, proszę? – user1095108

+3

Czas życia tymczasowy zdefiniowany jest w § 12.2. (Sekcja 12 to zatytułowana "Specjalne funkcje użytkownika", która nie jest dokładnie taka, na jakiej spodziewałbyś się odszukać cały czas istnienia tymczasowych, ale to właśnie tam jest.) –

+0

@ user1095108 i czas życia argumentów funkcji można uzyskać z § 3.2.2 i §3.7.2 w standardzie C++ 03. – juanchopanza

5

Zwrot tymczasowy zwracany przez funkcję random_string_generator() może być bezpiecznie użyty w funkcji consumer().

Powiązane problemy