[ANSI C] Si guardo punteros dinamicos en un archivo ¿Debo hacer free?

Iniciado por Xargam, 25 Junio 2018, 10:10 AM

0 Miembros y 2 Visitantes están viendo este tema.

Xargam

Si guardo varios punteros a estructura reservados con malloc en un archivo de texto o binarios, debo liberar esos punteros?

MAFUS

No debes guardar esos punteros a un archivo porque no vas a guardar la estructura sino solo su dirección. Es cómo cuándo hace años la gente iba a un cibercafé y creía que copiando los accesos directos de los juegos se los podía llevar a casa.
Con eso vengo a decir que cuándo quieras recuperar los datos del archivo en otro momento ya no existirán y lo que habrá en esa zona de memoria que has guardado será basura, o directamente no pertenecerá al ámbito de la memoria del programa.
Para guardar una estructura debes guardar miembro a miembro, si son punteros (como por ejemplo cadenas) debes guardar el contenido de dónde apunta el puntero. A la hora de recuperar los datos debes hacerlo en el mismo orden en que fueron guardados (y en el caso de datos tipo cadena, el número exacto de bytes que guardaste). Esto se debe hacer así por el hecho de que de un programa a otro, de una máquina a otra, la instancia del programa puede ordenar, de forma interna, la estructura de forma diferente para acomodarla de forma específica a ese entorno.

Xargam

Gracias! Y una pregunta mas... Si yo declaro un doble puntero con malloc.

void** pointer =(void**) malloc(sizeof(void*) *10 );

Tendria 10 direcciones  de memoria cuyo elemento deberian ser un puntero simple a void...
si digo:

free(pointer)

tambien libera las direcciones de memoria contiguas que malloc me reservo?
es decir pointer+1, pointer+2 ... ¿No las puedo liberar no por separado no, a dichas direcciones no las tengo en una variable puntero.

engel lex

Citartambien libera las direcciones de memoria contiguas que malloc me reservo?

No y es donde vienen principalmente los desbordes de memoria, al hacer free solo libera el vector pasado, entonces tienes que con un ciclo liberar los hijos y así hasta llegar al raiz
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Xargam

Libera el vector osea todos eso doble puntero que reserve se liberan entonces? Pero claro dentro de ese vector se guardaban punteros que  contienen otras direcciones alas que free no llega ... Pero si hablamos de esto:

int** pointer = malloc(int**)malloc(sizeof(int*)*10 );

Reserve esto:

(pointer + 0);
(pointer + 1);
(pointer + 2);
(pointer + 3);
(pointer + 4);
(pointer + 5);
(pointer + 6);
(pointer + 7);
(pointer + 8);
(pointer + 9);

podria hacer esto:

*(pointer + 1) = (int*)malloc(sizeof(int));
*(pointer + 2) = (int*)malloc(sizeof(int));

Si yo quiero liberar el ARRAY doble punteros pero NO lo que guarda cada puntero.
Entonces debo hacer esto:

free(pointer);

y se habria liberado
(pointer + 0);
(pointer + 1);
(pointer + 2);
(pointer + 3).... ??????
pero no se habria liberado pointer[0][0];verdad???

MAFUS

Correcto. Si haces un array de punteros dinámicos, antes de liberar el array debes liberar todos los punteros dinámicos que has generado.

Piénsalo de esta forma:
Un array, tanto dinámico como estático como cualquier otra variable, es una entrada en una tabla donde se guarda la dirección de inicio y su tamaño, a parte de su nombre y algunas cosas más.

Cuando se accede a una posición de un array se tiene en cuenta su dirección de inicio, el número de elemento y el tamaño de éstos elementos. Por tanto si liberas el array de punteros dinámicos quitarás de la tabla ese array pero los elementos existentes siguen ocupando memoria que, por el hecho de haber liberado el array y no existir más su referencia, no podrás acceder a ellos.

Por cierto, en tiempo de ejecución esa tabla no existe y todo son posiciones y offsets. Dicha tabla solo existe de forma interna para el compilador para construir el código.

Xargam

Excelente! Muchisimas gracias por tu aporte mafus!! tengo una duda mas y ya esta :D
Cuando yo guardo datos dentro de un archivo binario, se guarda el contenido no?
La direccion de memoria solo se necesita para el copiado verdad(junto con los bytes)?


FILE* pf;

int vector[5]={0,1,2,3,4};

pf = fopen("numeros.bin","wb");

fwrite(vector,sizeof(int),5,pf );

fclose(pf);

Serapis

No es lógico, tantas preguntas sobre el tema...

Para qué termines de entenderlo de una vez, te pongo un eemplo simplón, asequible a todo el mundo (incluído niños de 8 años).

- Imagina que tienes un vehículo, coche (carro), moto, bicileta, etc... esto es como el dato en programación, una variable... el objeto que nos interesa hacer algo con él.
- Ahora imagina que has ido a trabajar en tu vehículo... lo aparacas en un  estacionamiento... la plaza donde está aparcado, trayendo el ejemplo a la programación, equivale a la dirección donde consta el dato (la plaza donde yace el vehículo)...

- Así vehículo y plaza ocupada, guardan exactamente la misma relación que dato y su localización en memoria. Piensa en ello, lo que no es razonable en uno, tampoco lo es en otro y viceversa...

Lógicamente mañana, puedes aparacar en esa misma plaza, pero posiblemente sea otra y seguramente cuando termines de trabajar, irás a otra parte y por tanto la plaza será otra... La plaza no se garantiza, por tanto tú necesitas saber siempre donde lo tienes aparcado y no dar por hecho que está en un sitio u otro siempre... pués lo mismo con los datos...

- Por tanto, la plaza donde aparcas es importante, pero ese dato no puede retenerse eternamente como si fuera única... tu vehículo (una variable), si será el mismo pero, puede o no estar aparacardo en una dirección u otra en cualquier momento dado. Luego igualmente no conviene guardar punteros de forma indefinida, sino a cada instante que se precise, tenerlo y mantenerlo y olvidarlo... exactamente igual que la plaza donde está aparacado tu vehículo, ahora está aquí, luego lo mueves y estará alló y puede que un momento ni recuerdes donde está, así que pulsarás el botoncito que incorpora el mando a distancia (que se incluye en el llavero), para hacelro sonar y reconocer donde está...

- Nada de la informática es un 'invento único', siempre se basa en experiencias cotidianas, o bien puede asemejarse bastante a dichas cosas...