Pregunta devolver una variable local de la función en C [duplicado]


Esta pregunta ya tiene una respuesta aquí:

#include <stdio.h>

int foo1(void)
{
    int p;
    p = 99;
    return p;
}

char *foo2(void)
{
    char buffer[] = "test_123";
    return buffer;
}

int *foo3(void)
{
    int t[3] = {1,2,3};
    return t;
}

int main(void)
{
    int *p;
    char *s;

    printf("foo1: %d\n", foo1());
    printf("foo2: %s\n", foo2());
    printf("foo3: %d, %d, %d\n", p[0], p[1], p[2]);
    return 0;
}

Cuando compilo esto con gcc -ansi -pedantic -W -Wall el compilador emite mensajes de advertencia para foo2 () y foo3 ():

warning: function returns address of local variable

Pensé que no está permitido devolver una variable local, pero foo1 () funciona bien y parece que hay una gran diferencia entre regresar el puntero a un objeto local y el objeto en sí.

¿Alguien podría arrojar algo de luz sobre este tema? ¡Gracias por adelantado!


32
2018-01-28 02:43


origen


Respuestas:


El problema aquí es que cuando se crea la variable local, se asigna en la pila y, por lo tanto, no está disponible una vez que la función finaliza la ejecución (la implementación varía aquí). La forma preferible sería usar malloc() para reservar memoria no local. el peligro aquí es que tienes que desasignar (free()) todo lo que asignó usando malloc(), y si lo olvida, crea una pérdida de memoria.


21
2018-01-28 02:49



por foo1(), devuelves un dupdo de la variable local, no la variable local en sí.

Para las otras funciones, devuelve una copia de un puntero a una variable local. Sin embargo, esa variable local se desasigna cuando la función finaliza, por lo que terminas con problemas desagradables si tratas de referenciarla después.


16
2018-01-28 02:48



Cualquier variable tiene espacio en la memoria. Un puntero hace referencia a ese espacio. El espacio que ocupan las variables locales se desasigna cuando regresa la llamada a la función, lo que significa que puede reutilizarse para otras cosas. Como consecuencia, las referencias a ese espacio van a terminar señalando algo completamente diferente. Las matrices en C se implementan como punteros, por lo que esto termina aplicando a ellos. Y las matrices constantes declaradas en una función también cuentan como locales.

Si desea utilizar una matriz u otro puntero más allá del alcance de la función en la que se creó, debe usar malloc para reservar el espacio correspondiente. El espacio reservado utilizando malloc no se reasignará ni reutilizará hasta que se libere explícitamente llamando gratis.


5
2018-01-28 02:46



Sí, está devolviendo una matriz, que en realidad es un puntero detrás de las escenas, a la dirección de la ubicación de la memoria donde se almacena el contenido de la variable que ha inicializado. Por lo tanto, le advierte que puede que no sea tan útil devolver ese resultado, cuando en realidad podría querer decir uno de los valores de la matriz.


0
2018-01-28 02:49