|
|||||||
|
|
|
|||||
|
|
|||||||
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.
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;
IMPLEMENTACIONESEST reserv_mem(void)
{
EST temp = NULL;
temp = (EST) malloc(sizeof(T_EST));
return temp;
}
* Reserva de memoria par los campos dato y cadEST 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.