Fabio Cicerchia
Fabio Cicerchia

Reputation: 679

How to save a dynamic struct to file

I have something like this, in fact more complex struct than this:

typedef struct _sample {
    unsigned char type;
    char *name;
    test *first;
} sample;
typedef struct _test {
    test *prev;
    test *next;
    char *name;
    int total;
    test_2 **list;
} test;
typedef struct _test_2 {
    char *name;
    unsigned int blabla;
} test_2;
sample *sample_var;

I want to backup this struct into a file and after restore it.

I also try with fwrite(sample_var, sizeof(sample), 1, file_handle); but the real problem is sizeof(sample) that return wrong size, not real variable size.

There is a way to save it into file & restore without knowing the size?

Upvotes: 2

Views: 2581

Answers (4)

Lohrun
Lohrun

Reputation: 6752

There is no easy approach to save such a structure into a file. For instance, even the sample.name field has a size of 4 (depending on architecture), while what you probably want to save is the content of the memory pointed by sample.name.

Here is a sample code that will do such a thing. You will have to duplicate the process to save the entire structure.

void saveToFile(FILE *fh, sample s)
{
  fwrite(s.type, sizeof(char), fh);
  int nameSize = strlen(s.name); // get the length of the name field
  fwrite(nameSize, sizeof(size_t), fh); // write the length of the name field
  frwite(s.name, nameSize * sizeof(char), fh); // write the content of the name field
  // continue with other fields
}

The idea is to store the size of the next structure and then writting the content. To get the information from the file, you read the size, and then get the data.

Upvotes: 1

cnicutar
cnicutar

Reputation: 182619

You are trying to serialize, or marshal the structure. You can't just fwrite the data (having pointers is the most obvious stopper). The sizeof problem is really minor when compared to storing pointers in a file (a pointer is meaningless outside the program where it originated).

You will have to define your own serialization / deserialization functions. You could either use your own simple format or use JSON, XML, XDR or something like that.

Personally I would go with JSON, since it's all the rage these days anyway.

As an aside, here is a C FAQ vaguely linked to your own question (though it discusses interoperabillity issues).

Upvotes: 4

nobsid
nobsid

Reputation: 186

It seems like what you really want to do is store the struct and what it's pointer's are referring to, not the pointers themselves.

You will need to write some logic the determine the size of the the data being pointed at, and write that data to the file instead of the pointers.

Upvotes: 0

Benjamin Monate
Benjamin Monate

Reputation: 314

sizeof(sample) is not incorrect: it returns the size of a char followed by two pointers. If you need to save such a recursive data type, you have to manually follow dereference the pointers.

Upvotes: 0

Related Questions