elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [C] [?] Función free() y uso posterior
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [C] [?] Función free() y uso posterior  (Leído 3,015 veces)
iplazlac

Desconectado Desconectado

Mensajes: 2


Ver Perfil
[C] [?] Función free() y uso posterior
« en: 21 Noviembre 2010, 15:19 pm »

Hola, tengo un problemilla con la función free() en c. Tengo una "tabla" con claves y valores , la estructura es la siguiente.

Código
  1. /* Definicion del tipo */
  2. typedef struct {
  3.  size_t capacidad;
  4.  size_t numElementos;
  5.  size_t tamClave;
  6.  size_t tamValor;
  7.  void *claves;
  8.  void *valores;
  9.  FuncionComparacion compara;
  10. } Tabla;
  11.  

Asignacion de memoria:

Código
  1. /* Crea una tabla. El booleano devuelto indica si se pudo crear la tabla */
  2. bool tablaCrea( Tabla * tablaA, size_t capacidad, size_t tamClave, size_t tamValor, FuncionComparacion compara ){
  3.  bool res=true;
  4.  tablaA->capacidad=capacidad;
  5.  tablaA->tamClave=tamClave;
  6.  tablaA->tamValor=tamValor;
  7.  tablaA->compara=compara;
  8.  tablaA->numElementos=0;
  9.  tablaA->claves=(void *) malloc (tamClave*capacidad);
  10.  tablaA->valores=(void *) malloc (tamValor*capacidad);
  11.  if(tablaA->claves== NULL || tablaA->valores==NULL ||compara==NULL||capacidad==0||tamClave==0||tamValor==0||tablaA==NULL)
  12.    res=false;
  13.  return res;
  14. }
  15.  

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
  1. /* Indica si la tabla es o no valida */
  2. bool tablaEsValida( Tabla *tablaA ){
  3.  return (tablaA!=NULL);
  4. }
  5.  
  6. /* Libera la tabla.  El valor devuelto indica si la operación se ha podido
  7.    realizar */
  8. bool tablaLibera( Tabla *tablaA ){
  9.  if(tablaA!=NULL){
  10.    free(tablaA->claves);
  11.    tablaA->claves=NULL;
  12.    free(tablaA->valores);
  13.    tablaA->valores=NULL;
  14.    free(tablaA);
  15.    tablaA=NULL;
  16.    return true;
  17.  }else{
  18.    return false;
  19.  }
  20. }
  21.  

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
  1.    /* Liberamos la tabla y comprobamos que deja de ser válida*/
  2.    tablaLibera( &tablaIntInt );
  3.    assert( !tablaEsValida( &tablaIntInt ) );
  4.  
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.


« Última modificación: 21 Noviembre 2010, 17:01 pm por iplazlac » En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: [C] [?] Función free() y uso posterior
« Respuesta #1 en: 21 Noviembre 2010, 17:58 pm »

¡Buenas!

El problema esta en que a la funcion que libera los datos le pasas un puntero a Tabla. A efetos practicos, ese puntero es como si fuese una variable local, por lo tanto todos los cambios que realices sobre el puntero (no sobre el objeto al que apunta), solo afectaran a esa "variable local" y no al objeto al que apunta. Es decir, si haces que ese puntero se NULL, no haras que un puntero exterior que hubieses puesto en la lista de parametros sea NULL. Recuerda el problema del intercambio:

Código
  1.  
  2. void intercambio(int *a,int *b) //para poder modificar enteros exteriores usamos punteros
  3. {
  4.    int aux;
  5.  
  6.    aux = *a;
  7.    *a = *b;
  8.    *b = aux;
  9. }
  10.  
  11.  

Lo mismo ocurre con los punteros, si quieres modificar un puntero exterior a la funcion, deberas pasar un puntero a ese puntero, y luegoya trabajar con el, asi que suponiendo que el reto de tu codigo este bien, y que a la funcion liberar le pases un puntero, tendras que cambiar la llamada de la funcion para pasar un puntero a ese puntero y cambiar el codigo dentro de la funcion asi:

Código
  1. bool tablaLibera( Tabla **tablaA ){
  2.  if(*tablaA != NULL){
  3.    free((*tablaA)->claves);
  4.    (*tablaA)->claves=NULL;
  5.    free((*tablaA)->valores);
  6.    (*tablaA)->valores=NULL;
  7.    free((*tablaA)); //Ahora si que estas modificando un puntero exterior a la funcion
  8.    (*tablaA)=NULL;//Ahora si que estas modificando un puntero exterior a la funcion
  9.    return true;
  10.  }else{
  11.    return false;
  12.  }
  13. }
  14.  


Como ves, el funcionamiento de las dos funciones es similar. En una desreferenciamos un entero, y en la segunda desreferenciamos un puntero a un puntero a Tabla, asi en la primera modificamos un entero exterior a la funcion, y en la segunda modificamos un puntero a Tabla exterior a la funcion.

¡Saludos!


En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
iplazlac

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Re: [C] [?] Función free() y uso posterior
« Respuesta #2 en: 21 Noviembre 2010, 18:35 pm »

Hola do-while.
Muchas gracias por tus explicaciones, me han sido de mucha utilidad.
Problema solucionado.
Un saludo.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[AYUDA] Vulnerabilidad encontrada y posterior explotación.
Nivel Web
kub0x 1 2,218 Último mensaje 15 Julio 2011, 08:57 am
por Shell Root
Reemplazar la función free por una propia.
Programación C/C++
NOB2014 6 2,804 Último mensaje 26 Abril 2016, 02:51 am
por NOB2014
Unlocker_1.9.2 o posterior
Software
Zorronde 3 1,563 Último mensaje 10 Junio 2019, 02:49 am
por Zorronde
Sony SoudFORGE v.11 o posterior « 1 2 »
Software
Zorronde 13 3,146 Último mensaje 30 Junio 2019, 15:13 pm
por Zorronde
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines