Free Web Site - Free Web Space and Site Hosting - Web Hosting - Internet Store and Ecommerce Solution Provider - High Speed Internet
Search the Web

Memoria Dinámica

Estructuras con campos punteros.

Cuando a un campo puntero se le asigna memoria, al liberar la variable de tipo estructura, este campo (el espacio), sigue existiendo en memoria.
La diferencia radica en que ya es imposible acceder a través de la variable de tipo estructura, a estas zonas de memoria reservadas anteriormente.
Por lo tanto si se quiere liberar memoria a este tipo de campos, se lo tiene que hacer a través de punteros auxiliares o implementado una función que libere los campos y la variable.

Ej :

Declaramos una estructura con los siguientes punteros :

int *ptr : Sólo va a almacenar una dirección de memoria.
int *dato : Se reservara memoria para almacenar un dato ( 10 ).
char *cad : Se reservara memoria para apuntar a un string.

typedef struct
{
   int *ptr,*dato;
   char *cad;
} T_EST,*EST;
IMPLEMENTACIONES

* Reserva de memoria para la estructura

EST reserv_mem(void)
{
    EST temp = NULL;
    temp = (EST) malloc(sizeof(T_EST));
    return temp;
}
* Reserva de memoria par los campos dato y cad

EST reserv_campos(EST aux)
{
    aux->ptr = NULL;
    aux->dato = (int *) malloc(sizeof(int));
    aux->cad = (char *) malloc(10 * sizeof(char));
    return aux;
}

Como parámetro, debe recibir un puntero ya inicializado, o sea aux debe ser distinto de NULL.

Una alternativa que fusiona estas dos funciones podría ser :

EST memoria(void)
{
    EST t = reserv_mem();
    if (t != NULL) t = reserv_campos(t);
    return t;
}

* Imprimir en pantalla, la dirección en memoria de los campos de la estructura

void imp_dir_campos(EST aux)
{
    printf("\n\n Direcciones de los campos");

    printf("\n Dir ptr  : %p",&aux->ptr);
    printf("\n Dir dato : %p",&aux->dato);
    printf("\n Dir cad  : %p",&aux->cad); 
}

* Imprimir en pantalla, el contenido e indirección de los punteros

void imp_contenido(EST aux)
{
    printf("\n\n Contenido de los campos");
    printf("\n ptr = %p , *ptr = %d ",aux->ptr , *(aux->ptr));
    printf("\n dato = %p , *dato = %d ",aux->dato , *(aux->dato));
    printf("\n cad = %p , *cad = %s",aux->cad ,aux->cad);
}
* Programa principal
int main()
{

    EST t = reserv_mem();
    t = reserv_campos(t);
    
    imp_dir_campos(t);

/* salida :
    Dir ptr   = 00780EB0
    Dir dato = 00780EB4
    Dir cad  = 00780EB8
*/

/* Asignacion de valores a los campos  */
    
    int k = 5;
    t->ptr = &k;
    *(t->dato) = 10;
    strcpy(t->cad ,"PRUEBA");

    imp_contenido(t);

/* salida :
    ptr   = 0065FDF0 ,  *ptr = 5
    dato = 00780E80 ,  *dato = 10
    cad  = 00780E40 ,  *cad = PRUEBA
*/

/* Se guardan las direccion de los tres campos (punteros), 
a través de punteros dobles */

     int **dp1 = &t->ptr; 
     int **dp2 = &t->dato; 
     char **dp3 = &t->cad; 

/* Se crean dos punteros auxilares, para almacenar las direcciones 
contendidas en t->dato y t->cad , antes de liberar memoria de 
variable t  */
    
    
     int *aux_dato = t->dato; 
     char *aux_cad = t->cad;  

/* Se libera memoria para la variable t   */

     free(t);
    
     printf("\n\n DESPUES DE LIBERAR LOS CAMPOS...");
    
     imp_dir_campos(t);

/* salida :
    Dir ptr   = 00780EB0
    Dir dato = 00780EB4
    Dir cad  = 00780EB8
*/

/* Se observa que las direccones de los campos se mantienen donde mismo.
A continuación veremos que los contenidos de esos punteros se modifican  */

    printf("\n Contenido de t->ptr = %p",*dp1);    
    printf("\n Contenido de t->dato = %p",*dp2);
    printf("\n Contenido de t->cad = %p",*dp3);

/*salida : 
    Contenido de t->ptr =   DDDDDDDD
    Contenido de t->dato = DDDDDDDD
    Contenido de t->cad =  DDDDDDDD
*/

/* DDDDDDDD = "dirección basura" , por lo tanto, ya no se puede indireccionar 
a traves de la variable (estructura) t  */

/* A continuación se observa que las reservas de memoria se mantienen
donde mismo, pero el acceso se hace a través de los punteros auxiliares */


     printf("\n Contenido de aux_dato = %p",aux_dato);
     printf("\n *aux_dato = %d",*aux_dato);

     printf("\n Contenido de aux_cad = %p",aux_cad);
     printf("\n *aux_cad = %s ",aux_cad);

/* salida :
    Contenido de aux_dato = 00780E80
    *aux_dato = 10
    Contenido de aux_cad = 00780E40
    *aux_cad = PRUEBA
*/

/* Se libera memoria para los dos punteros. Luego, los
datos se pierden, ya que al indireccionar se imprime "basura"  */

     free(aux_dato);
     printf("\n *aux_dato = %d",*aux_dato);
    
     free(aux_cad);
     printf("\n *aux_cad = %s \n\n",aux_cad);

/* salida :
    *aux_dato = -123342342345454
    *aux_cad = ##############A
*/

     return 0;
}

Nota : este programa fue compilado, en Visual C++ de Microsoft.