Floris
Floris

Reputation: 518

Is this a correct way of freeing multiple dynamically allocated arrays that are part of a struct?

I am working on C code that reads in binary files, and organises the data contained in these files into a struct before processing. In its most concise form, the main function is structured as follows: 1) read_hgf_file 2) process_contents 3) free_allocated_memory

Because the data consists of recordings at different points in space, the most convenient is to organise the data in a struct with arrays. I have included the definition of this struct in a header file "read_hgf.h", which looks as follows (I am using MSVS 2017):

#pragma once
struct HGF {
    int32_t Nrows;
    int32_t Ncols;
    int32_t Np;
    float *data;
    float *xcoords;
    float *ycoords;
    float *zcoords;
};

The first three fields help to define the size of the latter four. In my main function, I call a function that fills these fields with the data from the binary file, which works fine. At the end now, I want to free the dynamically allocated memory associated with this struct. Because it looks messy if I free these arrays one-by-one in the main function, I want to wrap this functionality in a function free_hgf(). Did I understand correctly that I have to free these fields one-by-one, just as they are declared? Would the following be a correct way of doing that, or am I violating any C rules/best practices (particularly related to the combination of the * and -> operators)?

function:

#include "read_hgf.h"
void free_hgf(struct HGF **hgf) {
free((*hgf)->zcoords);
free((*hgf)->ycoords);
free((*hgf)->xcoords);
free((*hgf)->data);
*hgf = NULL;

}

Called from main as follows:

#include "read_hgf.h"
struct HGF hgf;
struct HGF *hgfPtr = &hgf;
free_hgf(&hgfPtr);

Thanks in advance!

Upvotes: 1

Views: 80

Answers (1)

xvnm
xvnm

Reputation: 481

I assume that the function which fills HGF structure is written by you and members of HGF structure are allocated with malloc, like

void read_hgf(struct HGF * hgf)
{
    ...

    hgf->data = malloc(...);
    hgf->xcoords = malloc(...);
    hgf->ycoords = malloc(...);
    hgf->zcoords = malloc(...);

    ...
}

Usage of the structure would be

struct HGF hgf;

read_hgf(&hgf);

...

free_hgf(&hgf);

and freeing part,

void free_hgf(struct HGF * hgf) // single pointer is enough to pass a structure
{
    free(hgf->zcoords);
    free(hgf->ycoords);
    free(hgf->xcoords);
    free(hgf->data);

    // clear members
    hgf.data = NULL;
    ...
}

Remember if you allocated memory N times (with malloc, realloc, ...), after you've done using them, you must call free N times.

Upvotes: 3

Related Questions