Search code examples
cpointersstructfwrite

How to write struct that has pointer in it


I have a struct that has a pointer to another struct:

typedef struct _contacts
{
    Contact *elements;
    int length;
    int capacity;
} Contacts;

and this is my Contact struct:

typedef struct _contact
{
    int id;
    char firstName[NAME_SIZE];
    char lastName[NAME_SIZE];
    char address[ADDRESS_SIZE];
    char email[EMAIL_SIZE];
    char phoneNumber[NUMBER_SIZE];
    char homeNumber[NUMBER_SIZE];
} Contact;

When I try to write Contacts on a binary file using fwrite,

Contacts *contacts = newEmptyContacts();
// do something with contacts...
fwrite(contacts, sizeof(Contacts), 1, file);

it writes a pointer to Contact, which I don't want.

How can I store each element of Contacts along side length and capacity members?


Solution

  • It's normal that your code writes a pointer to the file, that's simply what you're asking your code to do. Instead of writing the contacts structure you need to write the elements of contacts. You also need to write the number of contacts somehow, so the code that will read the file knows how many contacts to read:

    Assuming length is the actual number of contacts and capacity is the available storage space, your code should roughly be something like this:

    Contacts *contacts = newEmptyContacts();
    // do something with contacts...
    
    // write the number of contacts and capacity to the file    
    fwrite(&contacts.length, sizeof(contacts.length), 1, file);
    fwrite(&contacts.capacity, sizeof(contacts.capacity), 1, file);
    
    // write all contacts to the file
    fwrite(contacts.elements, sizeof(Contact), contacts.length, file);
    

    The read code could be something like this:

    int length;
    int capacity;
    
    // read the length from the file    
    fread(&length, sizeof(length), 1, file);
    
    // read the capacity from the file    
    fread(&capacity, sizeof(capacity), 1, file);
    
    // allocate a Contacts structure for length contacts
    Contacts *contacts = newContacts(capacity);  
    
    // read length contacts from the file
    fread(contacts.elements, sizeof(Contact), length, file);
    contacts.length = length;
    ...
    
    Contacts *newContacts(int capacity)
    {
      Contacts *contacts = malloc(capacity* sizeof(*contacts));
      contacts->capacity = capacity;
      contacts->length = 0;
      return contacts;
    }
    

    Disclaimer: this is untested code, it may contain errors and there is no error checking at all, but you should get the idea.