Otra de C + malloc + free

Buenas, estoy desarrollando un software para generar aplicaciones paralelas sintéticas para investigación, y cuando ya creía tenerlo acabado, al añadir dos funcionalidades nuevas, me da un error de memoria.

El error que da es el siguiente:

*** glibc detected *** malloc(): memory corruption (fast): 0x08052228 ***

Nada que decir, típico error de algún puntero perdido. Información aportada, nula, salvo que sabemos que es por posiciones de memoria.

Lo tengo controlado, es decir, se que trozo de código lo produce, lo pongo a continuación:

else

{

mode=1;

fargv=(char **)malloc(sizeof(char *)*40);

while (!feof(arxiu))

{

fargv[0]=(char *)malloc(sizeof(NOM));

strcpy(fargv[0],NOM);



fargc=1;

entra=0;

fgets(s1,LINIA_ARXIU,arxiu);

ptr = strtok( s1, s2 );


if (ptr!=NULL)

{
//LA SIGUIENTE LÍNEA PRODUCE EL FALLO
fargv[fargc]=(char *)malloc(sizeof(ptr));
strcpy(fargv[fargc],ptr);



while( (ptr = strtok( NULL, s2 )) != NULL )

{

entra=1;

fargc++;

fargv[fargc]=(char *)malloc(sizeof(ptr));

strcpy(fargv[fargc],ptr);

}

fargc++;

if (entra==1)

ProcessarArguments(fargc,fargv);



for (i=(fargc);i>0;i--)//Se libera memoria

free(fargv[i-1]);



}



mode++;

}


Explico lo que hace éste trozo de código y comento lo del error.

Este codigo se encarga de leer una serie de argumentos que contiene un fichero, línea a línea, y secuenciar a estas, es decir, por ejemplo:

-g 3 -s 3 -c [1000,2000] -m 100 -i 3 -t 2 -w -o file1
-s 3 -g 4 -c [5000,6000] -m [1,200] -t 2 -w -i 5 -o file3
-s 12 -d 4 -c [1,50] -m 90 -i 2 -t 2 -w -o file4

Contiene líneas de este tipo, y se encarga de ponerlas secuenciadas una a una dentro del array fargv, parametro por parametro. De modo que cuando tengo una línea ejecuto todo el programa, y así línea a línea.

El problema viene, cuando he ejecutado la primera línea, todo correcto, hago el free, y empiezo a recoger datos de la segunda, pero cuando llego a esa línea, es decir, hago un malloc de fargv[1] previamente liberado en el for del final, me da el error.

Sé que el error está ahí, también sé como solucionarlo, quitando el for que libera memoria, si lo hago así no peta.

Pero por otro lado, no veo correcto tener empleada una memoria que no voy a usar, y estar reservando memoria sobre memoria anteriormente reservada.

Es decir, sé como corregirlo pero no me parece muy correcto.

Existe alguna manera alternativa de solucionarlo?

Saludos y gracias!!
fargv[fargc]=(char *)malloc(sizeof(ptr));
strcpy(fargv[fargc],ptr);


Este código es fundamentalmente erróneo. Intuyo que ptr es un 'char *' porque es lo que devuelve strtok*.

Estás reservando espacio para un puntero en 'fargv[fargc]' y luego intentas copiar alli los contenidos de '*ptr' hasta un NULL.

Intuyo que quieres reemplazar ese malloc(sizeof(ptr)) por malloc(strlen(ptr)) pero no he mirado mucho más el código.

PD: BTW, el estándar de C _REQUIERE_ que un puntero se pueda convertir a void* y vuelta al puntero implícitamente. Así que ese casting lo único que hace es afear el códio y quizá esconder bugs.

- ferdy
Ferdy escribió:Intuyo que quieres reemplazar ese malloc(sizeof(ptr)) por malloc(strlen(ptr)) pero no he mirado mucho más el código.


No he entendido muy bien esta parte, no se si quieres decir que DEBO cambiarlo. Lo he hecho y funciona igualmente, si tengo el for con el free suelta el error y si lo saco funciona maravillosamente.

La pregunta que formulaba en el primer post (perdón si no estaba clara) es que si quedaría muy feo sacar el for con el free del final de la función, o si hay alguna forma de hacerlo de manera que no suelte error en la segunda iteración.

Saludos.
Jose.
El problema no está en los free, el problema es que haces una gestión brutalmente anal de la memoria. Esa parte del código que he apuntado está mal y tienes que corregirla. Y esta tambien:

fargv[0]=(char *)malloc(sizeof(NOM));
strcpy(fargv[0],NOM);


Te empeñas en reservar memoria para un puntero (NOM) e intentar copiar su contenido en otro sitio..... Probablemente quieras usar http://www.opengroup.org/onlinepubs/009695399/functions/strdup.html . A no ser que NOM esté definido como un array 'estático' y entonces tengas potenciales 'Buffer Overflows' en todo tu código. Si puedes pegar la definición de las variables, mejor :)

El hecho de que la corrupción ocurra en el 'free' solo indica que estás haciendo algo mal ANTES. (A no ser que modifiques los punteros de 'fargv' en ProcessarArguments; pasa fargv como 'const char *const' a ver si es eso.

- ferdy
exacto, como bien apunta ferdy, reservas espacio para un puntero e intentas copiar su contenido en el espacio reservado, por lo tanto eso petara cuando tengas un contenido realmente grande supongo.

Ah por cierto, que co*o son "aplicaciones paralelas sintéticas para investigación" ? :Ð
Hola de nuevo y perdón por la ausencia.

Primero decir que el problema quedó arreglado, he puesto las sentencias como decías Ferdy, pero al final he tenido que dejar fuera el free, como dije antes.

Por otro lado, tranquilo Cat_Os_Mandros, no es un programa realizado para tratar con información muy grande.

En cuanto a lo del título del proyecto, se trata de un programa que entrados unos parámetros como por ejemplo, número de etapas, número de tareas, coste de las tareas, coste de comunicación....

Genera un archivo .c, y un archivo .xml, y el grafo de ejecución de un programa "paralelo", con esto me refiero a un programa para ejecutarse en un cluster, con comunicación MPI.

Y claro, lo de sintéticas, es porque los programas que genera más o menos siguen todos un patrón, recibe-computa-envia, y no tienen una utilidad real, más que para hacer comparativas, benchmarks y demás.

Espero haber aclarado un poco las dudas que tenías. Jajaja.

Saludos y gracias!!
5 respuestas