Hola, tengo un problemilla con la función free() en c. Tengo una "tabla" con claves y valores , la estructura es la siguiente.
Asignacion de memoria:
Vale, ya tengo mi tabla con sus bloques de memoria reservada para las claves y valores, hasta ahora todo correcto. El problema viene cuando libero la tabla, tengo tambien otra funcion para verificar si la tabla es o no válida. Os las adjunto ambas.
Lo que se de free() hasta ahora:
- Un programador prudente haria :
free(puntero);
puntero=NULL;
Por si se da un acceso posterior al free(), el comportamiento no estaría definido.
-free() no devuelve nada.
-Si haces free() de un puntero nulo sencillamente no hace nada, no hay problema.
Hasta aqui yo creo que esta todo correcto, pero al hacer la siguiente comprobación:
El assert falla, parece ser que despues de liberar a tablaEsValida() no le llega como NULL. Tabla deberia salir NULL de liberaTabla() pero no se muy bien como no le llega como NULL a tablaEsValida().
Un saludo y mucha gracias por vuestro tiempo por adelantado.
PD. No se si me he pasado de codigo o datos, pero prefiero que tengais informacion de sobra que no que falte.
Código (C) [Seleccionar]
/* Definicion del tipo */
typedef struct {
size_t capacidad;
size_t numElementos;
size_t tamClave;
size_t tamValor;
void *claves;
void *valores;
FuncionComparacion compara;
} Tabla;
Asignacion de memoria:
Código (C) [Seleccionar]
/* Crea una tabla. El booleano devuelto indica si se pudo crear la tabla */
bool tablaCrea( Tabla * tablaA, size_t capacidad, size_t tamClave, size_t tamValor, FuncionComparacion compara ){
bool res=true;
tablaA->capacidad=capacidad;
tablaA->tamClave=tamClave;
tablaA->tamValor=tamValor;
tablaA->compara=compara;
tablaA->numElementos=0;
tablaA->claves=(void *) malloc (tamClave*capacidad);
tablaA->valores=(void *) malloc (tamValor*capacidad);
if(tablaA->claves== NULL || tablaA->valores==NULL ||compara==NULL||capacidad==0||tamClave==0||tamValor==0||tablaA==NULL)
res=false;
return res;
}
Vale, ya tengo mi tabla con sus bloques de memoria reservada para las claves y valores, hasta ahora todo correcto. El problema viene cuando libero la tabla, tengo tambien otra funcion para verificar si la tabla es o no válida. Os las adjunto ambas.
Código (C) [Seleccionar]
/* Indica si la tabla es o no valida */
bool tablaEsValida( Tabla *tablaA ){
return (tablaA!=NULL);
}
/* Libera la tabla. El valor devuelto indica si la operación se ha podido
realizar */
bool tablaLibera( Tabla *tablaA ){
if(tablaA!=NULL){
free(tablaA->claves);
tablaA->claves=NULL;
free(tablaA->valores);
tablaA->valores=NULL;
free(tablaA);
tablaA=NULL;
return true;
}else{
return false;
}
}
Lo que se de free() hasta ahora:
- Un programador prudente haria :
free(puntero);
puntero=NULL;
Por si se da un acceso posterior al free(), el comportamiento no estaría definido.
-free() no devuelve nada.
-Si haces free() de un puntero nulo sencillamente no hace nada, no hay problema.
Hasta aqui yo creo que esta todo correcto, pero al hacer la siguiente comprobación:
Código (C) [Seleccionar]
/* Liberamos la tabla y comprobamos que deja de ser válida*/
tablaLibera( &tablaIntInt );
assert( !tablaEsValida( &tablaIntInt ) );
El assert falla, parece ser que despues de liberar a tablaEsValida() no le llega como NULL. Tabla deberia salir NULL de liberaTabla() pero no se muy bien como no le llega como NULL a tablaEsValida().
Un saludo y mucha gracias por vuestro tiempo por adelantado.
PD. No se si me he pasado de codigo o datos, pero prefiero que tengais informacion de sobra que no que falte.