1

I have two structs

struct obj_t {
    int id;
    float x;
    float y;
};

struct cluster_t {
    int size;
    int capacity;
    struct obj_t *obj;
};

As you can see, there is pointer to first obj_t inside cluster_t

What I want to do is to free every obj_t from array inside cluster_t

Do I have to write it with for loop like this?

void clear_cluster(struct cluster_t *c)
{
    for(int i = 0; i<c->size;i++)
    {
        free(&c->obj[i]);
    }
    free(c->obj);
}

Or is it ok to free the memory just like this ?

void clear_cluster(struct cluster_t *c)
{
    free(c->obj);
}
3
  • 1
    By the reverse of the sequence where you allocated. Commented Dec 3, 2016 at 18:09
  • 1
    "As you can see array of obj_t is inside cluster_t" -- I cannot see any array inside cluster_t. I can see a pointer but that's a different thing. Commented Dec 3, 2016 at 18:35
  • There neither is a pointer to array in your struct! Commented Dec 3, 2016 at 18:36

2 Answers 2

5

There should be one free() for every malloc() you have, and executed in the opposite order from which it was allocated.

The field obj of cluster_t is a pointer to an array of object_t. This is probably allocated with one malloc() when initializing your cluster_t (something like c->obj = malloc(c->capacity*sizeof(*c->obj))), so it only needs to be freed with one call to free(). You would then want to free the cluster_t allocation itself (assuming it too was dynamically allocated):

free(c->obj);
free(c);

There would be a difference, however, if each object_t itself had a dynamic allocation within it. (In your example, object_t does not.) In that case, you would have needed to iterate through the array and malloc() an allocation when you created the array, and therefore do the reverse and free() each at the end.

Sign up to request clarification or add additional context in comments.

1 Comment

@HynekBernard the struct cluster_t also has members int size and int capacity which suggest that the memory allocated to the member struct obj_t *obj might be expanded with realloc() one or more times. That counts as a single allocation and only needs one free.
2

It depends on how you allocated. It seems you did something like

struct cluster_t cluster;
cluster.obj = malloc(sizeof (struct obj_t) * SOMENUMBER);

in this case, cluster.obj is just a pointer to an array. All you need to do is

free(cluster.obj)

or

free(c->obj)

in that function which receives a pointer to c.

You only have to iterate over the array calling free if you have an array of pointers.

Remember that & takes the memory address of the variable. You don't free the pointer, you free the memory that the pointer points to. You will never do something like free(&pointer).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.