2011-12-15 25 views
5

Considere el siguiente código:C - Devolver un puntero char sin malloc

char* pointerTesting(void) { 

    char* test = "hello"; 
    return test; 
} 

int main() { 

    char* string = pointerTesting(); 
    printf("string: %s\n", string); 
} 

Esto no tiene ningún problema en la compilación y ejecución. Sin embargo, en mi entender, esto no debería funcionar, ya que la memoria asignada al puntero test está en la pila y se destruye al volver a la principal.

Entonces la pregunta es, ¿cómo funciona esto sin un malloc en la función pointerTesting()?

+3

Consulte http://stackoverflow.com/questions/2589949/c-string-literals-where-do-theygo y un montón de preguntas similares sobre este tema en stackoverflow. – jman

+0

El * puntero * está asignado en la pila (para implementaciones típicas), pero no está devolviendo el puntero, solo una copia si es su valor. Es similar a 'int n = 42; return n; '. Es la asignación de lo que señala que es relevante. –

Respuesta

13

En este caso, la cadena "hello" se almacena en la memoria global *. Así que es ya asignado asignado.

Por lo tanto, sigue siendo válido cuando regrese de la función.

Sin embargo, si se hizo esto:

char test[] = "hello"; 
return test; 

Entonces no, no funcionaría. (comportamiento indefinido) En este caso, la cadena es en realidad una matriz local, que ya no está activa cuando la función regresa.

* Aunque este suele ser el caso, la norma no indica que deba almacenarse en la memoria global.
Pero la parte importante es que la duración de una cadena literal es la duración de todo el programa. (ver comentarios)

+0

Estaría más feliz si su respuesta mencionara que el '' hola '' está en la memoria global por un accidente de implementación y _no_ debido al comportamiento proscrito en cualquier estándar. – sarnold

+0

@sarnold De acuerdo, ¿debería cambiarlo a "* normalmente * almacenado en la memoria global"? ¿O debería decir "está almacenado * en otro lugar *"? – Mysticial

+0

Me gusta el asterisco que tienes ahora. :) ¡Gracias! – sarnold

5

Usted está devolviendo el valor de test, que es la dirección del primer carácter de la cadena literal "hello" (que, al igual que todos los literales de cadena, se almacena como una matriz de char de tal manera que esté disponible durante la vida del programa). Si estaba tratando de devolver la dirección de test para un uso posterior, entonces sí, tendría problemas.

Ahora el siguiente fragmento haría no trabajo:

char *pointerTesting(void) 
{ 
    char test[] = "hello"; 
    return test; 
} 

En este caso, usted está tratando de devolver la dirección del primer elemento en un objeto de matriz que es local a la función, que se ser inválido una vez que la función sale. Recuerde que en la mayoría de los contextos, una expresión de tipo "matriz de elementos N de T" será reemplazada por una expresión de tipo "puntero a T" cuyo valor es la dirección del primer elemento en la matriz.

Cuestiones relacionadas