Почему вызов c_str () для функции, которая возвращает строку, не работает?

У меня есть функция, возвращающая строку. Однако, когда я вызываю его и делаю c_str () на нем, чтобы преобразовать его в const char *, он работает только тогда, когда я сначала храню его в другой строке. Если я прямо вызываю функцию c_str (), она сохраняет значение мусора в const char *.

Почему это происходит? Почувствуй, что мне не хватает чего-то очень фундаментального здесь …

string str = SomeFunction(); const char* strConverted = str.c_str(); // strConverted stores the value of the string properly const char* charArray= SomeFunction().c_str(); // charArray stores garbage value static string SomeFunction() { string str; // does some string stuff return str; } 

SomeFunction().c_str() дает вам указатель на временную (автоматическая переменная str в теле SomeFunction ). В отличие от ссылок, время жизни временных charArray в этом случае не расширяется, и вы charArray являющийся висящим указателем, объясняющим значение мусора, которое вы видите позже, когда пытаетесь использовать charArray .

С другой стороны, когда вы это делаете

 string str_copy = SomeFunction(); 

str_copy – это копия возвращаемого значения SomeFunction() . Вызов c_str() теперь дает вам указатель на действительные данные.

Объект value, возвращаемый функцией, является временным. Результаты c_str() действительны только через время жизни временного. Время жизни временного в большинстве случаев заканчивается полным выражением, которое часто является точкой с запятой.

 const char *p = SomeFunction(); printf("%s\n", p); // p points to invalid memory here. 

Обходной путь состоит в том, чтобы убедиться, что вы используете результат c_str() перед окончанием полного выражения.

 #include  char *strdup(const char *src_str) noexcept { char *new_str = new char[std::strlen(src_str) + 1]; std::strcpy(new_str, src_str); return new_str; } const char *p = strdup(SomeFunction.c_str()); 

Обратите внимание: strdup – это функция POSIX, поэтому, если вы являетесь платформой, поддерживающей POSIX, она уже существует.

  1. « string str » в методе SomeFunction() является локальной переменной в SomeFunction() и только выживает внутри области SomeFunction() ;

  2. Поскольку возвращаемый тип метода SomeFunction() является строкой, а не ссылкой на строку, после « return str; », SomeFunction() вернет копию значения str , которая будет храниться как временное значение в некотором месте памяти, после вызова SomeFunction() временное значение будет немедленно уничтожено;

  3. string str = SomeFunction(); ” сохранит возвращенное временное значение SomeFunction() в строку str , фактически является копией этого значения и сохраняется на str , выделяется новый блок памяти, а время жизни str больше, чем возвращаемое временное значение SomeFunction() , после « ; » завершение вызова функции SomeFunction() , и возвращаемое временное значение немедленно уничтожается, память перерабатывается системой, но копия этого значения все еще сохраняется на str , Вот почему « const char* strConverted = str.c_str(); » может получить правильное значение, на самом деле c_str() возвратил указатель начального элемента str (адрес ячейки первого элемента str string), а не возвращает временное значение SomeFunction() ;

  4. « const char* charArray= SomeFunction().c_str(); » отличается, « SomeFunction().c_str() » возвращает указатель на начальный элемент возвращаемого временного значения (первый адрес памяти элемента возвращенной временной строки value), но после вызова SomeFunction() возвращаемое временное значение уничтожается и этот адрес памяти повторно используется системой, charArray может получить значение этого адреса памяти, но не ожидаемое значение;

Используйте strcpy для копирования строки в локально определенный массив, и ваш код будет работать нормально.

  • Нарисуйте строку в JPanel с нажатием кнопки на Java
  • Разница между + и & для присоединения строк в VB.NET
  • Измените строку с помощью указателя
  • Как получить подстроку в C #?
  • Подобный строковый алгоритм
  • Получение и удаление первого символа строки
  • Как преобразовать строку в нижний регистр в Bash?
  • Использование strtok () в цикле в C?
  • Как определить, не определена ли строка в сценарии оболочки bash?
  • Что делает сравнение ссылок (==) для некоторых строк в Java?
  • Объединение вектора строк / символа
  • Давайте будем гением компьютера.