Em um dos meus programas, tenho que fazer interface com algum código legado com o qual funciona const char*
.
Digamos que tenho uma estrutura parecida com:
struct Foo
{
const char* server;
const char* name;
};
Meu aplicativo de nível superior lida apenas com std::string
, então pensei em usar std::string::c_str()
para obter const char*
dicas de volta .
Mas qual é a vida útil de c_str()
?
Posso fazer algo assim sem enfrentar um comportamento indefinido?
{
std::string server = "my_server";
std::string name = "my_name";
Foo foo;
foo.server = server.c_str();
foo.name = name.c_str();
// We use foo
use_foo(foo);
// Foo is about to be destroyed, before name and server
}
Ou devo copiar imediatamente o resultado de c_str()
para outro lugar?
Obrigado.
.c_str()
. Não entendi porque às vezes recebo apenas partes do fio, até que entendi que oconst char*
não vive para sempre, mas até que o fio seja destruídoRespostas:
O
c_str()
resultado torna-se inválido se ostd::string
for destruído ou se uma função membro não const da string for chamada. Portanto, geralmente você desejará fazer uma cópia dele se precisar mantê-lo por perto.No caso do seu exemplo, parece que os resultados de
c_str()
são usados com segurança, porque as strings não são modificadas enquanto estão nesse escopo. (No entanto, não sabemos o queuse_foo()
ou podemos~Foo()
estar fazendo com esses valores; se eles copiarem as strings em outro lugar, eles devem fazer uma cópia verdadeira , e não apenas copiar oschar
ponteiros.)fonte
non-const member function of the string is called.
?const
palavra - chave. Tal função pode alterar o conteúdo da string, caso em que a string pode precisar realocar a memória para a versão terminada em nulo da string retornada porc_str()
. Por exemplo,size()
elength()
sãoconst
, para que você possa chamá-los sem se preocupar com a mudança da string, masclear()
não éconst
.Tecnicamente, seu código está bom.
MAS você escreveu de uma forma que torna mais fácil quebrá-lo para alguém que não conhece o código. Para c_str (), o único uso seguro é quando você o passa como um parâmetro para uma função. Caso contrário, você se expõe a problemas de manutenção.
Exemplo 1:
Portanto, para manutenção, deixe-o óbvio:
Melhor solução:
Mas se você tiver strings const, na verdade não precisa delas:
ESTÁ BEM. Por algum motivo, você os quer como strings:
Por que não usá-los apenas na chamada:
fonte
É válido até que um dos seguintes aconteça com o
string
objeto correspondente :Você está bem com o seu código, a menos que modifique esses
string
objetos apósc_str()
s serem copiados,foo
mas antes deuse_foo()
ser chamado.fonte
O valor de retorno de c_str () é válido apenas até a próxima chamada de uma função de membro não constante para a mesma string
fonte
O
const char*
retornado dec_str()
só é válido até a próxima chamada não const para ostd::string
objeto. Neste caso, você está bem porque seustd::string
ainda está no escopo por toda a vida deFoo
e você não está fazendo nenhuma outra operação que alteraria a string ao usar foo.fonte
Contanto que a string não seja destruída ou modificada, usar c_str () está OK. Se a string for modificada usando um c_str () retornado anteriormente, a implementação é definida.
fonte
Para completar, aqui está uma referência e citação de cppreference.com :
fonte