使用C中的动态数组和gsl_vectors写入和读取结构

时间:2014-07-05 23:44:02

标签: c serialization gsl

我的结构类似于:

typedef struct FOO {

  int m,n;
  int * am;
  gsl_vector * bn;

} foo;

为了分配这个结构,我做了:

foo * bar; 
bar=foo_alloc ( 10, 10 ); 

其中

foo * foo_alloc ( int m, int n ) {
  foo * f = (foo*)malloc(sizeof(foo));

  f->m=m;
  f->n=n;
  f->am=(int*)calloc(m,sizeof(int));
  f->bn=gsl_vector_calloc(n);
  return f;
}

我希望在二进制文件中编写条形码,然后再次阅读...我该怎么做?

谢谢!

编辑:

更具体地说,我尝试了

fwrite(&bar,sizeof(*bar),1,file)

但是sizeof(*bar)无法正常工作,通过Google搜索,我发现sizeof不适用于内置动态数组的此类结构。

有没有办法获得酒吧的大小?

如果没有,我支持我必须为每个元素放置一个fwrite,但在这种情况下我不知道如何获得gsl_vector的大小,因为这也是另一个结构内部的动态数组。

1 个答案:

答案 0 :(得分:0)

sizeof(*bar)是正确的。这是&bar这是错的。由于bar是指针,因此不应使用address-of运算符。

此外,您只尝试编写结构并且没有编写动态分配的数组数据。实际上,编写结构是没有意义的,因为在回读数据时地址将无效。您应该只写出大小(mn)和数组数据。当你回读它时,你需要再次malloc/calloc结构和数组空间。

这是一个可运行的例子。我已将gsl_vector替换为double,以方便其他人投放。

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int m, n;
    int *am;
    double *bn;
} Foo;

void foo_write(Foo *f, FILE *file) {
    fwrite(&(f->m), sizeof(f->m), 1, file);
    fwrite(&(f->n), sizeof(f->n), 1, file);
    fwrite(f->am, sizeof(*(f->am)), f->m, file);
    fwrite(f->bn, sizeof(*(f->bn)), f->n, file);
}

Foo *foo_read(FILE *file) {
    Foo *f = malloc(sizeof(*f));
    fread(&(f->m), sizeof(f->m), 1, file);
    fread(&(f->n), sizeof(f->n), 1, file);
    f->am = malloc(f->m * sizeof(*(f->am)));
    f->bn = malloc(f->n * sizeof(*(f->bn)));
    fread(f->am, sizeof(*(f->am)), f->m, file);
    fread(f->bn, sizeof(*(f->bn)), f->n, file);
    return f;
}

Foo *foo_alloc(int m, int n) {
    Foo *f = malloc(sizeof(*f));
    f->m = m;
    f->n = n;
    f->am = calloc(f->m, sizeof(*(f->am)));
    f->bn = calloc(f->n, sizeof(*(f->bn)));
    return f;
}

void foo_print(Foo *f) {
    int i;
    printf("%d, %d\n", f->m, f->n);
    for (i = 0; i < f->m; ++i)
        printf("%d ", f->am[i]);
    putchar('\n');
    for (i = 0; i < f->n; ++i)
        printf("%.1f ", f->bn[i]);
}

void foo_free(Foo *f) {
    free(f->am);
    free(f->bn);
    free(f);
}

int main() {
    FILE *file; 
    Foo *bar;
    int i;

    bar = foo_alloc(5, 10);
    for (i = 0; i < bar->m; ++i)
        bar->am[i] = i;
    for (i = 0; i < bar->n; ++i)
        bar->bn[i] = i;


    file = fopen("foo.bin", "wb");
    foo_write(bar, file);
    fclose(file);

    foo_free(bar);

    file = fopen("foo.bin", "rb");
    bar = foo_read(file);
    fclose(file);

    foo_print(bar);

    return 0;
}

您可以像这样写gsl_vector(假设向量是独立的,即它们不共享数据块):

void foo_write(Foo *f, FILE *file) {
    size_t i;
    fwrite(&(f->m), sizeof(f->m), 1, file);
    fwrite(&(f->n), sizeof(f->n), 1, file);
    fwrite(f->am, sizeof(*(f->am)), f->m, file);
    for (i = 0; i < f->n; ++i)
        gsl_vector_fwrite(file, &(f->bn[i]));
}

Foo *foo_read(FILE *file) {
    size_t i;
    Foo *f = malloc(sizeof(*f));
    fread(&(f->m), sizeof(f->m), 1, file);
    fread(&(f->n), sizeof(f->n), 1, file);
    f->am = malloc(f->m * sizeof(*(f->am)));
    f->bn = malloc(f->n * sizeof(*(f->bn)));
    fread(f->am, sizeof(*(f->am)), f->m, file);
    for (i = 0; i < f->n; ++i)
        gsl_vector_fread(file, &(f->bn[i]));
    return f;
}