En uno de mis programas, tengo que interactuar con un código heredado que funciona con const char*
.
Digamos que tengo una estructura que se parece a:
struct Foo
{
const char* server;
const char* name;
};
Mi aplicación de nivel superior solo se ocupa de std::string
, así que pensé en usarla std::string::c_str()
para recuperar const char*
sugerencias.
Pero, ¿de qué dura la vida c_str()
?
¿Puedo hacer algo como esto sin enfrentar un comportamiento 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
}
¿O se supone que debo copiar inmediatamente el resultado de c_str()
a otro lugar?
Gracias.
.c_str()
. No entendía por qué a veces obtengo solo partes de la cadena, hasta que entendí queconst char*
no vive para siempre, sino hasta que la cadena se destruyeRespuestas:
El
c_str()
resultado se vuelve inválido sistd::string
se destruye o si se llama a una función miembro no constante de la cadena. Por lo tanto, por lo general, querrá hacer una copia si necesita conservarla.En el caso de su ejemplo, parece que los resultados de
c_str()
se usan de manera segura, porque las cadenas no se modifican mientras están en ese alcance. (Sin embargo, no sabemos quéuse_foo()
o~Foo()
podría estar haciendo con esos valores; si copian las cadenas en otro lugar, entonces deberían hacer una copia verdadera , y no solo copiar loschar
punteros).fuente
non-const member function of the string is called.
?const
palabra clave. Tal función podría mutar el contenido de la cadena, en cuyo caso la cadena podría necesitar reasignar la memoria para la versión terminada en nulo de la cadena devuelta porc_str()
. Por ejemplo,size()
ylength()
sonconst
, para que pueda llamarlos sin preocuparse por el cambio de cadena, peroclear()
no es asíconst
.Técnicamente, su código está bien.
PERO ha escrito de tal manera que es fácil de romper para alguien que no conoce el código. Para c_str (), el único uso seguro es cuando lo pasa como parámetro a una función. De lo contrario, se expone a problemas de mantenimiento.
Ejemplo 1:
Entonces, para el mantenimiento, hágalo obvio:
Mejor solucion:
Pero si tiene cadenas constantes, en realidad no las necesita:
OKAY. Por alguna razón, los quiere como cadenas:
¿Por qué no usarlos solo en la llamada?
fuente
Es válido hasta que ocurra una de las siguientes situaciones con el
string
objeto correspondiente :Está bien con su código a menos que modifique esos
string
objetos después de quec_str()
se copien los correos electrónicosfoo
pero antes de queuse_foo()
se llame.fuente
El valor de retorno de c_str () es válido solo hasta la próxima llamada de una función miembro no constante para la misma cadena
fuente
La
const char*
devolución dec_str()
solo es válida hasta la próxima llamada no constante alstd::string
objeto. En este caso, está bien porquestd::string
todavía está dentro del alcance de la vida útil deFoo
y no está realizando ninguna otra operación que cambie la cadena mientras usa foo.fuente
Siempre que la cadena no se destruya o modifique, usar c_str () está bien. Si la cadena se modifica utilizando un c_str () devuelto previamente, se define la implementación.
fuente
Para completar, aquí hay una referencia y una cita de cppreference.com :
fuente