fwrite with structs containing an array
Question
How do I fwrite a struct containing an array
#include <iostream>
#include <cstdio>
typedef struct {
int ref;
double* ary;
} refAry;
void fillit(double *a,int len){
for (int i=0;i<len;i++) a[i]=i;
}
int main(){
refAry a;
a.ref =10;
a.ary = new double[10];
fillit(a.ary,10);
FILE *of;
if(NULL==(of=fopen("test.bin","w")))
perror("Error opening file");
fwrite(&a,sizeof(refAry),1,of);
fclose(of);
return 0;
}
The filesize of test.bin is 16 bytes, which I guess is (4+8) (int + double*). The filesize should be 4+10*8 (im on 64bit)
~$ cat test.bin |wc -c
16
~$ od -I test.bin
0000000 10 29425680
0000020
~$ od -fD test.bin -j4
0000004 0,000000e+00 7,089709e-38 0,000000e+00
0 29425680 0
0000020
thanks
Solution
You are writing the pointer (a memory address) into the file, which is not what you want. You want to write the content of the block of memory referenced by the pointer (the array). This can't be done with a single call to fwrite. I suggest you define a new function:
void write_my_struct(FILE * pf, refAry * x)
{
fwrite(&x->ref, sizeof(x->ref), 1, pf);
fwrite(x->ary, sizeof(x->ary[0]), x->ref, pf);
}
You'll need a similar substitute for fread.
OTHER TIPS
Your structure doesn't actually contain an array, it contains a pointer. If you really want variable-length structures, you'll need to keep a size field in there so that you know how big it is. The C FAQ has an example of exactly what it looks you're trying to do. In your case it might look something like this:
typedef struct {
int ref;
double ary[1];
} refAry;
#define SIZE_OF_REFARY (sizeof(refAry) - sizeof(double))
To allocate:
size_t alloc_size = SIZE_OF_REFARY + 10*sizeof(double);
refAry *a = malloc(alloc_size);
a->ref = 10;
To write:
fwrite(a, SIZEP_OF-REFARY + a->ref * sizeof(double), 1, file);
Your structure contains a pointer, not an array of 10. the sizeof() picks that up.
You'll need something like fwrite(a.ary, sizeof(double), 10, of); in order to write the actual array
If the size of the array is always 10, then simply change your struct to:
typedef struct {
int ref;
double ary[10];
} refAry;
You can then write this out with a single call to fwrite, using sizeof(refAry) for the size.