Dealing with Structures, Pointers, and Files

For pointer structures, the process of writing the structure to a file works similarly to writing a non-pointer structure, but it’s not without some pratfalls. Further, if you have a structure that contains a pointer, things get hinkey quickly.

When the code declares an array of structure pointers, the process of writing those structures to a file involves ensuring that you’re writing the data and not the pointer itself. For example:

struct person {
    char name[32];
    int age;
    float weight;
};
struct person *myself;

The struct person variable myself is a pointer. Storage must be allocated for the pointer to reference:

myself = (struct person *)malloc( sizeof(struct person) * 1);
if( myself == NULL)
{
    fprintf(stderr,"Unable to allocate memory\n");
    exit(1);
}

The malloc() function sets aside a chunk of memory equal to the sizeof the person structure. After success, the structure is filled with data:

strcpy( myself->name,"Dan Gookin");
myself->age = 58;
myself->weight = 679.1;

At this point, you can write the structure to a file. Use the fwrite() function as shown in this Lesson, but pay attention! What are you writing to the file?

Here is the proper fwrite() statement, assuming fp is an open file handle:

fwrite(myself,sizeof(struct person),1,fp);

And here is the improper fwrite() statement:

fwrite(&myself,sizeof(struct person),1,fp);

The address-of operator (&) isn’t required when writing a structure pointer because myself is already a pointer. If you apply the ampersand, you write the address of the myself structure and not the structure’s data.

The other pointer issue occurs when the structure contains a pointer member. I’ll be brief: Don’t even bother. The overhead required to write the pointer member’s data is too great and often too inconsistent to be worth the trouble. In fact, if you must write structures to a file, never include pointer members in the structure.

As an example, suppose the person structure were defined like this:

struct person {
    char *name;
    int age;
    float weight;
};
struct person *myself;

As the code runs, you’d allocate storage for the name pointer, fill the buffer, and so on. When it comes time to write the structure to a file, the sizeof operator returns only the bytes required to save the name pointer, not the buffer.

Suppose I allocate storage for name when the input is "Dan Gookin” (11 bytes). The name pointer member occupies only 4 bytes on my system. I just can’t think of a logical or consistent way to reference the buffer’s data without destroying the concept of writing specific-size chunks to a file. It’s too much of a bother, which is why I recommend not writing structures to a file when the structure includes pointer members.

Leave a Reply