Problemas al guardar un vector de registros

Jose Pablo
30 de Junio del 2003
Vamos a ver si puedo explicar bien cual es mi problema.

Tengo un registro de este tipo:

struct tipo_producto {
char desc[50];
int prec;
enum tmarca marca;
};

typedef struct tipo_producto producto;

Y creo un vector en memoria dinamica de productos:

producto *vector;
numelem = 4320;
vector = (producto *) calloc(numelem,sizeof(producto));

Relleno de elementos el vector mediante este procedimiento:

void rellena(producto *vector)
{
char *articulo[] = {"camisa ","pantalon ","jersey ","falda ","pa¤uelo "};
char *color[] = {"rojo ","amarillo ","verde ","azul ","blanco ","negro "};
char *tonalidad[] = {"claro ","oscuro ","brillante ","mate "};
char *talla[] = {"XXXL","XXL","XL","L","M","S"};
int x = 0;
int a,c,to,ta,m;
srand(time(0));
for (a = 0; a < 5; a++) {
for (c = 0; c < 6; c++) {
for (to = 0; to < 4; to++) {
for (ta = 0; ta < 6; ta ++) {
for (m = 0; m < 6; m++) {
strcat(vector[x].desc,articulo[a]);
strcat(vector[x].desc,color[c]);
strcat(vector[x].desc,tonalidad[to]);
strcat(vector[x].desc,talla[ta]);
vector[x].marca = m;
vector[x].prec = rand() % 10000 + 1;
x++;
}
}
}
}
}
}

Hasta aqui todo va perfectamente, el problema surge al guardar y recuperar el vector de fichero, para esto uso estos modulos:

void guardar(FILE *fich,producto *vector,int numelem)
{
fich = fopen("c:\vector.dat","wb");
if (fich == NULL) {
clrscr();
fprintf(stderr,"graba:error de fichero.");
exit(1);
}
fseek(fich,0,0);
fwrite(vector,sizeof(producto),numelem,fich);
fclose(fich);
}

int cargar(FILE *fich,producto *vector)
{
int n;
fich = fopen ("c:\vector.dat","rb");
if (fich == NULL) {
fprintf(stderr,"recupera:error en el fichero.");
exit(1);
}
fseek(fich,0,SEEK_END);
n = (int) ftell(fich) / sizeof(producto);
vector = (producto *) malloc(n * sizeof(producto));
fseek(fich,0,0);
fread(vector,sizeof(producto),n,fich);
fclose(fich);
return(n);
}

El problema está en que al recuperar es como si no lo hiciera bien y recupera datos raros, estoy ya muy quemado porque creo que hago un buen uso de las funciones pero no consigo dar con el problema. Gracias de antemano por la posible ayuda.

chuidiang
30 de Junio del 2003
Esta todo correcto salvo un pequeño detalle. Cuando a la funcion cargar() le pasas el puntero de vector, luego haces malloc() dentro de la función. El puntero vector se está pasando por copia, con lo que fuera de la función, el puntero que pases como parámetro, no apunta a la nueva dirección de memoria.
De hecho, si compruebas los valores de vector antes de salir de la función, verás que ha leido correctamente el fichero, pero si escribes los valores de los punteros vector y el que pasas desde fuera a cargar(), verás que apuntan a sitios distintos.
Para arreglar esto, debes pasar un doble puntero

main()
{
producto *punteroFuera;

cargar (... &punteroFuera);
}

int cargar (... , producto **punteroFuera)
{
...
*punteroFuera = (producto *)malloc (...);
}

En www.geocities.com/chuidiang tienes todo esto explicado con un poco más de detalle.

Se bueno.