Теперь у меня есть функция, которая должна возвратить строку. Я видел конкретную реализацию, куда он возвращает символ константы * из функции.
Что-то вроде этого:
const char * GetSomeString()
{
........
return somestlstring.c_str();
}
SomeOtherFoo ()
{
const char * tmp = GetSomeString();
string s = tmp;
}
Теперь я чувствовал, что существует что-то потенциально неправильно с этим. Действительно ли мое шестое чувство является правильным? или действительно ли это - совершенно безопасный код?
Любезно дайте мне свои предложения. У меня есть чувствительный символ константы возврата *, этот путь мог бы привести к опустошению..
Спасибо, Arjun
В зависимости от того, что такое somestlstring
и что там делается.
Если это локальная переменная, вы возвращаете указатель в память, который освобождается при завершении GetSomeString
, поэтому это висячий указатель и ошибка.
Все сводится к времени жизни somestlstring
и операциям, которые вы выполняете над ним. Указатель, возвращаемый функцией .c_str ()
, гарантированно действителен только до следующей операции изменения в строке. Итак, если что-то изменится somestlstring
от вызова .c_str ()
и до того, как s
будет сконструирован, вы попадете в страну неопределенного поведения.
Это нормально при условиях, которые описал @Neil. Однако лучшим способом было бы вернуть ссылку на строку
string const& GetSomeString()
{
........
return somestlstring;
}
string s = GetSomeString();
При этом следует помнить, что ´somestlstring´ не должна быть локальной автоматической переменной, а храниться где-то еще в пространстве имен или классе. В противном случае вы можете вернуть строку по значению
string GetSomeString()
{
........
return somestlstring; // can be a local automatic variable
}
string s = GetSomeString();
Это не здорово - как долго хранится память для вашей струны? Кто отвечает за его удаление? Нужно ли его вообще удалять?
Лучше вернуть строковый объект, который отвечает за выделение и освобождение строковой памяти - это может быть std :: string или QString (если вы используете Qt) или CString (если вы используете MFC / ATL).
немного по-другому, будет ли ваша строка когда-нибудь в кодировке Unicode? Большинство строковых классов могут прозрачно работать с данными Unicode, но const char не будет ...
Это зависит от того, где находится переменная somestlstring
.
Если это переменная локаль для функции GetSomeString ()
, то это явно неверно. Действительно, переменная somestlstring
уничтожается в конце функции, и, таким образом, const char *
указывает на то, что больше не существует.
Если это глобальная переменная, то этот код правильный.
Чтобы добавить несколько сценариев, в которых это будет нормально:
somestlstring
- глобальная переменная, инициализированная в той же единице перевода (.cpp) поскольку GetSomeString () somestlstring
является нестатическим членом класса, а GetSomeString является членом этого класса. В этом случае время жизни возвращаемого указателя должно быть задокументировано (в основном - как говорили другие - до тех пор, пока strign не изменится или объект не будет уничтожен) Если вы спрашиваете о времени жизни константы char *
, возвращаемый функцией std :: string
c_str ()
, он действителен до тех пор, пока вы не измените строку, из которой вы ее получили, или пока строка не будет уничтожена. Возврат его из функции - это нормально (хотя я бы сказал, что это не лучшая практика), если вы помните об этих двух фактах.