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