Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Duda liberar memoria dinámica

Iniciado por fgutierrez, 15 de Octubre de 2007, 02:24:50 PM

« anterior - próximo »

fgutierrez

Hola, buenas tardes. Llevo varios dias dándole vueltas a un asunto. Estoy implementando un tokenizador, y tengo problemas con la reserva y liberación dinámica de memoria. El fragmento de código que me esta dando problemas es el siguiente:


   /* Se lee el valor del parámetro Longitud del   símbolo Apex */

  p_cadena=p_cadena+2;
  char *param_cpy=(char*)calloc(strlen(&(cadena[p_cadena])),sizeof (char));
 strcpy(param_cpy,&(cadena[p_cadena]));
 char *lg=strtok(param_cpy,",");
 p_cadena=p_cadena+strlen(lg);
 *result=sscanf(lg,"%f",l);

 free(param_cpy);

Es decir, en primer lugar reservo memoria para la cadena param_cpy donde guardo una copia de la cadena de texto a 'tokenizar'. Con la llamada a la función strtok(param_cpy,'',") guardo en la cadena lg un determinado token. El problema viene cuando intento liberar la memoria antes reservada en la variable param_cpy, generándome la instrucción marcada en rojo un error en tiempo de ejecución. Creo que la razón del error tiene que ver con el funcionamiento de la función strtok, pero no logró llegar a comprender el porque de este mal funcionamiento. ¿Alguien podria ayudarme?

Gracias de antemano.

Fernando.
eamos realistas: Exijamos lo imposible

r2d2rigo

Tienes ese codigo en un bucle? Lo digo porque strtok devuelve un char* con el token encontrado, PERO si no lo encuentra devuelve NULL directamente. A ver si en la ultima iteracion estas usando un free(NULL) y por eso te peta :P


PD: hey, yo a ti te he visto por GameDev ;)

Tei

Lo he sangrado para ayudar al proximo aventurero, pero no he desentrañado ningun misterio del interior de la bestia.


  p_cadena = p_cadena + 2; // que es "2"? es sizeof(char)*2??
  char *param_cpy = (char*)calloc (
        strlen(&(cadena[p_cadena])
         ),
        sizeof (char)
  );

  if (!param_cpy)
    die("No hay memoria. Agite el dispositivo, y vuelva intentarlo.");

  strcpy( param_cpy , &(cadena[p_cadena]) );//??????????????
  // esto es algo como strcpy( param_cpy , cadena + p_cadena )?

  char *lg = strtok( param_cpy,","); //??
  p_cadena = p_cadena + strlen(lg); //??

 *result = sscanf( lg,"%f",l );

 if (param_cpy)  free(param_cpy); //no deberia ser necesario el if, creo
 


Estoy un poco oxidado. Igual en casa le hecho un vistazo en serio. Pero para entonces alguien ya habra descuvierto el misterio :D

fgutierrez

Cita de: "Tei"Lo he sangrado para ayudar al proximo aventurero, pero no he desentrañado ningun misterio del interior de la bestia.


  p_cadena = p_cadena + 2; /* Puntero para ir recorriendo cada  
                                              cada carácter de la cadena
       
  char *param_cpy = (char*)calloc (
        strlen(&(cadena[p_cadena])
         ),
        sizeof (char)
  );

  if (!param_cpy)
    die("No hay memoria. Agite el dispositivo, y vuelva intentarlo.");

  strcpy( param_cpy , &(cadena[p_cadena]) );//??????????????
  // esto es algo como strcpy( param_cpy , cadena + p_cadena )? Eso es.

  char *lg = strtok( param_cpy,","); //??
  p_cadena = p_cadena + strlen(lg); //??

 *result = sscanf( lg,"%f",l );

 if (param_cpy)  free(param_cpy); //no deberia ser necesario el if, creo
 


Estoy un poco oxidado. Igual en casa le hecho un vistazo en serio. Pero para entonces alguien ya habra descuvierto el misterio :D

Explico un poco que pretende hacer el código. Mi proyecto consiste en implementar un L-System, en principio algo sencillo, que se deberá utilizar para modelar  después mediante Open GL el crecimiento de árboles y plantas. Llendo al grano, en esta parte del código se recorre la cadena de símbolos generados, para lo cual se utiliza un puntero llamado 'p_cadena'. Si por ejemplo se encuentra en la cadena un símbolo A con dos parámetros 'A(l,t)', en esta parte del código se pretende recuperar el valor de esos dos parámetros. Por ello se implementa un tokenizador. El tema esta en que en esta parte del programa nos aseguramos de que la cadena analizado es sintácticamente correcta, por lo que el tokenizador siempre deberia devolver algo y nunca un NULL.
Muchas gracias por vuestra ayuda, y perdón si mi forma de programar es un tanto ilegible, pero estoy empezando y se puede decir que este es mi primer proyecto serio. Jeje, de hecho este es mi Proyecto Fin de Carrera.
eamos realistas: Exijamos lo imposible

fgutierrez

Cita de: "r2d2rigo"Tienes ese codigo en un bucle? Lo digo porque strtok devuelve un char* con el token encontrado, PERO si no lo encuentra devuelve NULL directamente. A ver si en la ultima iteracion estas usando un free(NULL) y por eso te peta :P

En todo caso si fuera eso lo que me ocurriera devolveria un NULL en la variable 'lg' y no en 'param_cpy' Aun así,me he asegurado de que la función strtok nunca me devuelva un NULL.

Cita de: "r2d2rigo"PD: hey, yo a ti te he visto por GameDev ;)

Si señor, jeje. La verdad que estoy ahora liado con el Proyecto Fin de Carrera y estoy registrado en varios foros. Supongo que me habrás visto en el foro de OpenGL preguntando cosas absurdas de principiante.

Muchas gracias por la ayuda, un saludo.
eamos realistas: Exijamos lo imposible

shephiroth

Buenas. Varios intentos intentos (espero no salirme demasiado de la diana y no darle a nadie en el ojo):

- El strcpy mejor ponlo como lo tienes en el comentario, quedando strcpy( param_cpy , (cadena + p_cadena) )

- Comprueba si a strtok has de pasarle la cadena principal todo el rato. Hace tiempo utilice una funcion similar (no se si es la misma) y solo habia que pasarle la cadena la primera vez, el resto de veces habia que pasarle null.

- Al usar calloc imagino que estas utilizando alguna libreria que administre la memoria. Comprueba que no tenga alguna funcion de borrado, que me parece lo mas normal.

- Has debugeado a ver si la funcion strtok te modifica tu variable de cadena?? no valla a ser que te la valla reduciendo y al final acabe apuntando a una zona de memoria no inicializada.

SUERTE

fgutierrez

Se me habia olvidado completamente que habia dejado este post abierto sin finiquitar la duda que planteaba. Finalmente encontré el error, y como suele ocurrir en estos casos fue la cosa más absurda que uno se pueda echar a la cabeza. Resulta que a la hora de reservar memoria para la cadena param_cpy no estaba reservando un espacio para el carácter Nulo. Vamos, que solucioné el asunto simplemente cambiando:


char *param_cpy = (char*)calloc (
        strlen(&(cadena[p_cadena])
         ),
        sizeof (char)
  );



por:

char *param_cpy = (char*)malloc (
        (strlen(&(cadena[p_cadena]) )+1) * sizeof (char) );


Cambié la instrución calloc por malloc porque descubrí que esta última supone menos carga para el sistema ya que no tiene la propiedad zero-filling que si posee la malloc. Muchas gracias por vuestra ayuda, un saludo.

Fernando Gutiérrez.
eamos realistas: Exijamos lo imposible






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.