Действительно ли это - хорошая идея возвратить “символ константы *” из функции?

Теперь у меня есть функция, которая должна возвратить строку. Я видел конкретную реализацию, куда он возвращает символ константы * из функции.

Что-то вроде этого:

const char * GetSomeString() 
{ 
  ........   
  return somestlstring.c_str(); 
}

SomeOtherFoo ()
{
  const char * tmp = GetSomeString();
  string s = tmp;
}

Теперь я чувствовал, что существует что-то потенциально неправильно с этим. Действительно ли мое шестое чувство является правильным? или действительно ли это - совершенно безопасный код?

Любезно дайте мне свои предложения. У меня есть чувствительный символ константы возврата *, этот путь мог бы привести к опустошению..

Спасибо, Arjun

25
задан AMM 25 March 2010 в 10:06
поделиться

6 ответов

В зависимости от того, что такое somestlstring и что там делается.

Если это локальная переменная, вы возвращаете указатель в память, который освобождается при завершении GetSomeString , поэтому это висячий указатель и ошибка.

Все сводится к времени жизни somestlstring и операциям, которые вы выполняете над ним. Указатель, возвращаемый функцией .c_str () , гарантированно действителен только до следующей операции изменения в строке. Итак, если что-то изменится somestlstring от вызова .c_str () и до того, как s будет сконструирован, вы попадете в страну неопределенного поведения.

27
ответ дан 28 November 2019 в 21:13
поделиться

Это нормально при условиях, которые описал @Neil. Однако лучшим способом было бы вернуть ссылку на строку

string const& GetSomeString() 
{ 
  ........   
  return somestlstring; 
}

string s = GetSomeString();

При этом следует помнить, что ´somestlstring´ не должна быть локальной автоматической переменной, а храниться где-то еще в пространстве имен или классе. В противном случае вы можете вернуть строку по значению

string GetSomeString() 
{ 
  ........   
  return somestlstring; // can be a local automatic variable
}

string s = GetSomeString();
3
ответ дан 28 November 2019 в 21:13
поделиться

Это не здорово - как долго хранится память для вашей струны? Кто отвечает за его удаление? Нужно ли его вообще удалять?

Лучше вернуть строковый объект, который отвечает за выделение и освобождение строковой памяти - это может быть std :: string или QString (если вы используете Qt) или CString (если вы используете MFC / ATL).

немного по-другому, будет ли ваша строка когда-нибудь в кодировке Unicode? Большинство строковых классов могут прозрачно работать с данными Unicode, но const char не будет ...

2
ответ дан 28 November 2019 в 21:13
поделиться

Это зависит от того, где находится переменная somestlstring .

Если это переменная локаль для функции GetSomeString () , то это явно неверно. Действительно, переменная somestlstring уничтожается в конце функции, и, таким образом, const char * указывает на то, что больше не существует.

Если это глобальная переменная, то этот код правильный.

1
ответ дан 28 November 2019 в 21:13
поделиться

Чтобы добавить несколько сценариев, в которых это будет нормально:

  • somestlstring - глобальная переменная, инициализированная в той же единице перевода (.cpp) поскольку GetSomeString ()
  • somestlstring является нестатическим членом класса, а GetSomeString является членом этого класса. В этом случае время жизни возвращаемого указателя должно быть задокументировано (в основном - как говорили другие - до тех пор, пока strign не изменится или объект не будет уничтожен)
  • вы возвращаете char const * в буквальную или инициализированную во время компиляции строку
2
ответ дан 28 November 2019 в 21:13
поделиться

Если вы спрашиваете о времени жизни константы char * , возвращаемый функцией std :: string c_str () , он действителен до тех пор, пока вы не измените строку, из которой вы ее получили, или пока строка не будет уничтожена. Возврат его из функции - это нормально (хотя я бы сказал, что это не лучшая практика), если вы помните об этих двух фактах.

6
ответ дан 28 November 2019 в 21:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: