2010-09-02 7 views
16

Cuando una función retorna, ¿se libera la memoria asignada mediante malloc? ¿O todavía se puede acceder en la función main() utilizando punteros?Alcance de malloc utilizado en una función

por ejemplo.

void function(int *a) 
{ 
    a=(int *)malloc(sizeof(int)); 
    *a=10; 
} 
int main() 
{ 
    int *num; 
    function(num); 
    printf("%d",*num); 
    return(0); 
} 

¿Puede el número entero almacenado en a ser accedido por main() aquí?

Respuesta

33

No, asigna la memoria con malloc no se libera cuando abandona el alcance/retorno de la función.

Usted es responsable de liberar la memoria que malloc.

En su caso, la memoria NO es accesible en main(), pero eso se debe a que solo se ocupa de una variable local.

void function(int *a) 
{ 
    a=(int *)malloc(sizeof(int)); 

Aquí, a es una variable local dentro function. Los punteros se pasan por valor en C, por lo que a recibe una copia del puntero en main cuando lo hace function(num); main() no ve que asigne a esa copia local del puntero.

que tiene que hacer, ya sea:

void function(int **a) 
{ 
    *a= malloc(sizeof(int)); 
    **a=10; 
} 
int main() 
{ 
    int *num; 
    function(&num); 
    printf("%d",*num); 
    free(num); 
    return(0); 
} 

o

int* function(void) 
{ 
    int *a= malloc(sizeof(int)); 
    *a=10; 
    return a; 
} 
int main() 
{ 
    int *num; 
    num = function(); 
    printf("%d",*num); 
    free(num); 
    return(0); 
} 
3

malloc() La memoria ed solo se libera cuando llama al free(). Cualquier persona con un puntero válido puede acceder a él hasta ese momento.

0

La memoria no se libera. Cualquier función puede asignar memoria y cualquier otra puede desasignarla. Es un verdadero desastre si no eres súper meticuloso, hasta que ... alguien inventó la Garbage Collection.

3

No. Está pasando el puntero num por valor, por lo tanto, los cambios realizados por function no se reflejarán en main. Así que efectivamente no hay manera de acceder a la/libre de la memoria asignada a main

Para solucionar este problema se puede pasar la dirección de num o volver a de la función y cobrar el valor devuelto en num

1

malloc está trabajando muy bien (aunque se tenga que llamar a free() en el puntero vuelve). El problema aquí es que no está devolviendo un puntero a la memoria que asignó.

"int * a", su parámetro para function() es la dirección de un entero. La forma habitual de rendimiento que se reescribir su función como sigue:

int * function() 
{ 
    int * a = (int *)malloc(sizeof(int)); 
    *a = 10; 
    return a; 
} 

para volverla a través de un parámetro, es necesario devolver la dirección del puntero:

// pp points to a pointer 
void function(int ** pp) 
{ 
    // Assign allocated memory to the thing that pp points to 
    *pp = (int *)malloc(sizeof(int)); 

    // Get the thing pp points to -- a pointer. 
    // Then get the thing which THAT pointer points to -- an integer 
    // Assign 10 to that integer. 
    **pp = 10; 
} 

void main() 
{ 
    int * p = NULL; 

    function(& p); 

    printf("%d\n", *p); 

    free(p); 
} 

Y ahora que sabes por qué inventaron C#.

Aquí está una manera de volver a escribir su cosa asignación por lo que es más claro:

void function(int ** pp) 
{ 
    int * newmemory = (int *)malloc(sizeof(int)); 

    // Assign 10 to the integer-sized piece of memory we just allocated. 
    *newmemory = 10; 

    // Assign allocated memory to the thing that pp points to. 
    *pp = newmemory; 
} 
0

Puede almacenar la dirección directa de la memoria asignada en un contenedor de lista a continuación, crear una función de bucle, acceder a cada dirección en una función libre, y luego pop-out la dirección. Puede insertar la dirección directamente en la función gratuita como free(myaddresslist.front()); myaddresslist.pop_front();. Esta es casi una manera de hacer su propia recolección de basura sin tener que cambiar todo su proyecto a lenguajes basados ​​en GC. Use myaddresslist.size() para asegurarse de no llamar a free() en un campo vacío (lo que da como resultado un bloqueo) y para determinar el número de bucles a tomar.