присваивание string :: c_str () const char *, когда строка выходит из области видимости - PullRequest
6 голосов
/ 14 ноября 2011

У меня есть сомнения в базовом использовании C ++.Приведенный ниже код, скомпилированный с помощью gcc / LInux, печатается правильно.

Строка test выходит из области видимости, поэтому ее значение c_str() также должно быть неверным, не так ли?Я ошибаюсь или я неправильно понял значение const char*?

   #include <iostream>
   int main(){
     const char* a = "aaaa";
       std::cout << a;
       { std::string test("bbbb");a=test.c_str();}
       std::cout << a;
       a = "cccc";
       std::cout << a;
   }


   aaaabbbbcccc
   // print out without any problem

Ответы [ 5 ]

13 голосов
/ 14 ноября 2011

Вы правы, ваш код недействителен, поскольку он использует объект, срок жизни которого уже закончился.Он работает «случайно», на это нельзя полагаться.

2 голосов
/ 14 ноября 2011

Это может быть из-за объединения строк. Тем не менее, это неопределенное поведение. Мы не должны использовать вывод c_str (), когда строка выходит из области видимости.

1 голос
/ 14 ноября 2011

Программа вызывает неопределенное поведение. Когда программа делает это, компилятор может делать все, что захочет, включая создание программы, которая работает так, как можно было бы ожидать.

Вероятная причина, по которой он работает так, как он работает, заключается в следующем. В конце внутреннего блока test выходит из области видимости и запускается его деструктор. Это освобождает блок памяти, используемый для хранения фактической строки для других целей, но память не очищается (это было бы пустой тратой времени). Освободившаяся память по той или иной причине не используется повторно до того, как bbbb будет распечатано.

(Обратите внимание, что назначение и распечатка cccc действительны.)

1 голос
/ 14 ноября 2011

Пока объект string выходит из области видимости, память, на которую указывает a, все еще будет там.Я не думаю, что стандарт говорит что-либо об очистке фактических областей памяти при разрушении строки.

0 голосов
/ 14 ноября 2011

Поскольку test выходит из области видимости, то, что вы делаете, это неопределенное поведение.Не делайте предположений о том, как он будет функционировать.

С таким же успехом это может привести к segfault, и поведение все равно будет правильным.UB - это UB.

...