¿Es una buena idea devolver “const char *” de una función?

Ahora tengo una función que tiene que devolver una cadena. Vi una implementación particular donde devuelve un const char * de la función.

Algo como esto:

const char * GetSomeString() { ........ return somestlstring.c_str(); } SomeOtherFoo () { const char * tmp = GetSomeString(); string s = tmp; } 

Ahora siento que hay algo potencialmente incorrecto con esto. Es mi instinto me siento bien? o ¿Es este un código perfectamente seguro?

Amablemente dame tus sugerencias. Tengo un sentimiento de retorno const char * de esta manera podría causar esgulps ..

Gracias, Arjun

Dependiendo de qué es somestlstring y qué se está haciendo allí.

Si se trata de una variable local, está devolviendo un puntero a la memoria que se está GetSomeString cuando GetSomeString finaliza, por lo que es un puntero colgante y un error.

Todo se reduce a la vida de somestlstring y las operaciones que realiza en él. Se garantiza que el puntero devuelto por .c_str() será válido solo hasta la siguiente operación de mutación en la cadena. Entonces, si algo cambia somestlstring de la llamada a .c_str() y antes de que s se construya, estarás en un territorio de comportamiento indefinido.

Si está preguntando sobre la duración de la función const char * devuelta por la función std::string c_str() , es válida hasta que modifique la cadena desde la que la obtuvo, o hasta que se destruya la cadena. Devolverlo de una función está bien (aunque yo diría que no es una buena práctica), siempre que tenga en cuenta esos dos hechos.

Esto está bien bajo las condiciones @Neil elaboradas. Sin embargo, una mejor manera sería devolver una referencia a la cadena

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

Aún teniendo en cuenta que ‘somestlstring` no debe ser una variable automática local, sino que debe almacenarse en otro lugar en un espacio de nombres o una clase. De lo contrario, puede devolver la cadena por valor

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

No es genial, ¿cuánto tiempo se queda la memoria de la cadena? ¿Quién es responsable de eliminarlo? ¿Necesita ser eliminado en absoluto?

Es mejor que devuelva un objeto de cadena que es responsable de asignar y liberar la memoria de cadena; esto podría ser una cadena estándar o una QString (si usa Qt) o CString (si está utilizando MFC / ATL).

en una nota ligeramente diferente, ¿su cadena será unicode? La mayoría de las clases de cadenas pueden tratar de forma transparente con datos Unicode, pero const char no …

Depende de dónde se encuentre la variable somestlstring .

Si se trata de una configuración regional variable para la función GetSomeString() , esto es claramente incorrecto. De hecho, la variable somestlstring se destruye al final de la función, y así el const char * apunta a algo que ya no existe.

Si es una variable global, entonces este código es correcto.

Para agregar algunos escenarios en los que esto estaría bien:

  • somestlstring es una variable global inicializada en la misma unidad de traducción (.cpp) que GetSomeString ()
  • somestlstring es un miembro de clase no estático, y GetSomeString es miembro de esa clase. En ese caso, la vida útil del puntero devuelto debe estar documentada (básicamente, como otros dijeron, hasta que la línea cambia o el objeto se destruye)
  • está devolviendo un char const * a una cadena inicializada literal o en tiempo de comstackción