fwrite со структурами, содержащими массив - PullRequest
2 голосов
/ 08 февраля 2010

Как мне написать структуру, содержащую массив

#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;
}

Размер файла test.bin составляет 16 байт, который, я думаю, равен (4 + 8) (int + double *). Размер файла должен быть 4 + 10 * 8 (им на 64-битной)

~$ 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

спасибо

Ответы [ 4 ]

2 голосов
/ 08 февраля 2010

Вы пишете указатель (адрес памяти) в файл, а это не то, что вам нужно. Вы хотите записать содержимое блока памяти, на который ссылается указатель (массив). Это невозможно сделать с помощью одного вызова fwrite. Я предлагаю вам определить новую функцию:

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);
}

Вам понадобится аналогичный заменитель хлеба.

1 голос
/ 08 февраля 2010

Ваша структура на самом деле не содержит массив, она содержит указатель. Если вам действительно нужны структуры переменной длины, вам нужно будет сохранить поле размера, чтобы вы знали, насколько оно велико. C FAQ содержит пример того, что именно вы пытаетесь сделать. В вашем случае это может выглядеть примерно так:

typedef struct {
    int ref; 
    double ary[1];
} refAry;

#define SIZE_OF_REFARY (sizeof(refAry) - sizeof(double))

Выделить:

size_t alloc_size = SIZE_OF_REFARY + 10*sizeof(double);
refAry *a = malloc(alloc_size);
a->ref = 10;

Написать:

fwrite(a, SIZEP_OF-REFARY + a->ref * sizeof(double), 1, file);
0 голосов
/ 08 февраля 2010

Если размер массива всегда равен 10, просто измените вашу структуру на:

typedef struct {
  int ref; 
  double ary[10];
} refAry;

Затем вы можете записать это одним вызовом fwrite, используя sizeof (refAry) для размера.

0 голосов
/ 08 февраля 2010

Ваша структура содержит указатель, а не массив из 10. sizeof () забирает это.

Вам понадобится что-то вроде fwrite (a.ary, sizeof (double), 10, of); для записи фактического массива

...