2010-03-25 22 views
22

Ahora tengo una función que debe devolver una cadena. Vi una implementación particular donde devuelve un const char * de la función.¿Es una buena idea devolver "const char *" de una función?

Algo como esto:

const char * GetSomeString() 
{ 
    ........ 
    return somestlstring.c_str(); 
} 

SomeOtherFoo() 
{ 
    const char * tmp = GetSomeString(); 
    string s = tmp; 
} 

Ahora me sentí hay algo potencialmente malo en esto. Es mi instinto me siento bien? o ¿Es este un código perfectamente seguro?

Agradecerme sus sugerencias. Tengo una sensación de retorno const char * de esta manera podría resultar en caos ..

Gracias, Arjun

Respuesta

26

Dependiendo de lo somestlstring es y lo que se hace allí.

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

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

6

Si se está preguntando acerca de la vida útil de la const char * devuelto por la función std::stringc_str(), es válido hasta que modifique la cadena lo obtuvo de, o hasta que la cuerda se destruye. 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.

2

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

Será mejor que devuelva un objeto de cadena que se encargue de asignar y liberar la memoria de serie - esto podría ser std :: string, o QString (si está usando Qt), o CString (si está usando MFC/ATL).

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

1

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, por lo tanto, el const char * apunta a algo que ya no existe.

Si se trata de una variable global, este código es el correcto.

3

Esto está bien bajo las condiciones @Neil elaborado. Sin embargo, una mejor manera sería para 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, pero almacenada en otro lugar en un espacio de nombres o de una clase.De lo contrario se puede devolver la cadena de valor

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

string s = GetSomeString(); 
+2

A menos que somestlstring sea local en el alcance de la función. :-) – Konrad

+2

@Konrad seguro, pero también dije eso en mi respuesta justo después de mostrar el código. :) –

1

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

  • somestlstring es una variable global inicializado en la misma unidad de traducción (.cpp) como 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 dijeron otros, hasta que la línea cambia o se destruye el objeto)
  • está devolviendo una cadena const * a una serie inicializada literal o en tiempo de compilación
Cuestiones relacionadas