Ok, he vuelto a programar después de un periodo de gracia. Ya veo que soy el único que utiliza la mesa de ayuda, en mes y medio nadie ha puesto nada -.-
El caso es este, tenía un error bastante curioso en un proceso que ejecutaba varias veces para sacar el tiempo medio que tarda el ordenador en ejecutarlo. Cuando lo ejecutaba menos de 10 veces funcionaba bien, pero a la décima se cascaba. Finalmente encontré el error, y es que había una variable que no inicializaba, y se me mezclaba con lo que había antes... Lo corregí, pero la pregunta es la siguiente: Cuando hago alloc a una variable, si el espacio que encuentra había sido utilizado por otra variable que ya no está en uso, el valor de esta variable no se borra??? O si esta no es la causa de lo que me pasaba, por qué, si a una variable le hago free y después alloc, resulta que tiene un valor inicial distinto del predeterminado??
Ahora que lo pienso el problema también puede ser de realloc, pues hago realloc de esas variables también
El código del proceso en cuestión, con las líneas susodichas rodeadas de barras:
[code language="bennu"]function jmath_obtener_descomposicion_factorial(jmath_numero numero, jmath_descomposicion_factorial resultado)
begin
if(jmath_igual(numero,jmath_cero))
say("ERROR: jmath_math: jmath_obtener_descomposicion_factorial(): Descomposicion factorial de cero");
exit();
end
resultado.numero_factores = 0;
resultado.signo = numero.signo;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(resultado.factores != 0) free(resultado.factores); resultado.factores = 0; end
if(resultado.exponentes != 0) free(resultado.exponentes); resultado.exponentes = 0; end
resultado.factores = alloc(sizeof(jmath_numero));
resultado.exponentes = alloc(sizeof(jmath_numero));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
jmath_formar_fraccion(numero,jmath_uno,fraccion_numero);
numerador_actual = fraccion_numero.numerador;
denominador_actual = fraccion_numero.denominador;
archivo_primos = fopen(jmath_path_primos,o_read);
for(indice_primo_actual = 1; indice_primo_actual <= jmath_numero_primos and (!jmath_igual(numerador_actual,jmath_uno) or !jmath_igual(denominador_actual,jmath_uno)); indice_primo_actual++)
jmath_formar_numero(atoi(fgets(archivo_primos)),primo_actual);
jmath_resto(numerador_actual,primo_actual,resto_actual);
if(jmath_igual(resto_actual,jmath_cero))
resultado.numero_factores++;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
resultado.factores = realloc(resultado.factores,(resultado.numero_factores+1)*sizeof(jmath_numero));
resultado.exponentes = realloc(resultado.exponentes,(resultado.numero_factores+1)*sizeof(jmath_numero));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
resultado.factores[resultado.numero_factores] = primo_actual;
resultado.exponentes[resultado.numero_factores] = jmath_cero;
jmath_resto(numerador_actual,primo_actual,resto_actual);
while(jmath_igual(resto_actual,jmath_cero))
jmath_suma(resultado.exponentes[resultado.numero_factores],jmath_uno,resultado.exponentes[resultado.numero_factores]);
******************************************************************************************
jmath_division(numerador_actual,primo_actual,numerador_actual);
jmath_resto(numerador_actual,primo_actual,resto_actual);
end
end
jmath_resto(denominador_actual,primo_actual,resto_actual);
if(jmath_igual(resto_actual,jmath_cero))
resultado.numero_factores++;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
resultado.factores = realloc(resultado.factores,(resultado.numero_factores+1)*sizeof(jmath_numero));
resultado.exponentes = realloc(resultado.exponentes,(resultado.numero_factores+1)*sizeof(jmath_numero));
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
resultado.factores[resultado.numero_factores] = primo_actual;
resultado.exponentes[resultado.numero_factores] = jmath_cero;
jmath_resto(denominador_actual,primo_actual,resto_actual);
while(jmath_igual(resto_actual,jmath_cero))
jmath_resta(resultado.exponentes[resultado.numero_factores],jmath_uno,resultado.exponentes[resultado.numero_factores]);
************************************************************************************************
jmath_division(denominador_actual,primo_actual,denominador_actual);
jmath_resto(denominador_actual,primo_actual,resto_actual);
end
end
end
fclose(archivo_primos);
end[/code]
El error lo detectaba poniendo un say de los valores de las variables en las líneas con asteriscos(utilizando un proceso para ver los valores de este tipo de variables)
Tanto resultado.factores como resultado.exponentes está declarado como jmath_numero pointer.
Gracias y un saludo.
te recomiendo leas esto.
http://man.cx/malloc(3)/es
http://linux.die.net/man/3/malloc
alloc = malloc
no se entiende bien lo que preguntas, si hablas de la variable puntero o del contenido del area alocada...
free no te modifica el valor de la variable, vos tenes que ponerla a NULL...
si despues de leer esto te quedan dudas, explica mejor con ejemplos, que es lo que obtenes y que es lo que vos pensas que deberias obtener y te explico el por que en base a esas dudas...
saludos.
QuoteCuando hago alloc a una variable, si el espacio que encuentra había sido utilizado por otra variable que ya no está en uso, el valor de esta variable no se borra???
yo de gestión de memoria casi no se nada... :D
quizá se refiere a esto:
http://c.conclase.net/librerias/funcion.php?fun=calloc
lo que pasa es que la función que borra es calloc, aunque no se si en bennu haya equivalente
eso es el contenido... no, en bennu no existe... pero...
hay 2 soluciones simples a eso:
1) malloc + memset
2) implementar la funcion calloc
ambas soluciones son simples... de momento usa la primera.
tene en cuenta que realloc, no limpia la memoria nueva asignada, asi que en esos casos tenes que hacer memset de la nueva porcion... (realloc = malloc + memmove)
je je, justamente ahora estaba viendo eso... muy interesante...
INT MEMSET(POINTER, BYTE, INTEGER)
INT MEMSETW(POINTER, WORD, INTEGER)
INT MEMSETI(POINTER, INTEGER, INTEGER)
a ver si ya me pongo a usar esto... ;) saludos
Quote from: HaCkZJuaNN on June 13, 2009, 06:58:22 PM
Cuando hago alloc a una variable, si el espacio que encuentra había sido utilizado por otra variable que ya no está en uso, el valor de esta variable no se borra??? O si esta no es la causa de lo que me pasaba, por qué, si a una variable le hago free y después alloc, resulta que tiene un valor inicial distinto del predeterminado??
Ésa es la pregunta. Ya sé que free libera la memoria pero no cambia el valor del puntero, por eso puedes ver en mi código que después de hacer free seteo los punteros a 0(que tú me dijiste es equivalente a null).
No he entendido muy bien lo que me decís :\. Lo que yo quiero saber es que si cuando hago alloc y/o realloc, asignándole un trozo de memoria a una variable, es posible que ese trozo de memoria, por causas muy diversas, tenga datos distintos de los predeterminados cuando creas una variable nueva. Es decir, si existe alguna diferencia entre el contenido de una variable a la que apunta un puntero cuando haces alloc y/o realloc Y el contenido de, por ejemplo, una variable privada declarada en un proceso que aún no se ha utilizado, DE TAL FORMA que cada vez que haga alloc y/o realloc tengo que setear esas variables a un valor que yo pueda controlar y que no sea uno completamente desconocido por mi.
Edit: Me acabo de dar cuenta de que las cosas que deberían estar en negrita o cursiva no lo están en el código :S Un segundo.
Edit2: Arreglado
Puede ser que no se "borre" y que la variable inicialice con un valor desconocido. Esto ocurre en muchos lenguajes por eso se recomienda darle a la variable un valor inicial nada más declararla. Tu caso no es extraño.
Un saludo.
no hay valores determinados en el bloque de memoria. es un area de memoria como este... claro que puede tener valores, anormal seria que este limpio.
yes, tenes que inicializarlo... y cuando hagas realloc, tenes que reinicializar el nuevo incremento, teniendo en cuenta que el puntero ahora puede cambiar.
Ok, ya veo. Gracias entonces. Lo curioso es que en la mayoría de los casos daba la casualidad de que estaba limpio, por eso me sorprendía cuando fallaba.
Un saludo.
Por cierto, perdonad mis errores que quizá son de falta de base, pero yo <<aún>> no he estudiado nada de informática, empiezo la universidad en septiembre, y todo lo que sé hasta ahora es a base de probar, preguntar y leer cosas; por eso ésto que a lo mejor os parece tan básico yo no lo sabía :P
inicialmente puede que este limpia, o quizas gran parte lo este... pero nada lo asegura...
no hay nada que disculpar.
Nada, no te preocupes.
ya esta incorporada la CALLOC o MEM_CALLOC