0

I'm allocating an array of of "Todo" structs on the heap like so:

struct Todo *todos = malloc(n * sizeof(*todos));

My understanding is that I have now allocated memory for all of my n Todo structs. So if I want to save some values I can just do for example:

todos[i].id = 1;

The problem now is that if I try to free that memory using free(&todos[i]); I get an error telling me that I haven't allocated that pointer.

My question is now, do I just need to free the todos array and not every element on its own?

asked Aug 1, 2018 at 15:16
4
  • stackoverflow.com/questions/4641476/… Commented Aug 1, 2018 at 15:18
  • 1
    You just have to call free on the pointer you saved, i.e. free(todos);. Commented Aug 1, 2018 at 15:18
  • Possible duplicate of Using Dynamic Memory allocation for arrays Commented Aug 1, 2018 at 15:18
  • Detail: "free the todos array" --> todos is a pointer, not an array. free(todos); frees the allocated memory pointer to by todos. Commented Aug 1, 2018 at 16:42

3 Answers 3

5

You have allocated one single block of memory for all your Todo structures. You can not free a single element. Just like you should not free elements of a non-heap allocated array.

Each call to malloc (or calloc) should be matched by a single call to free.

answered Aug 1, 2018 at 15:19
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your quick response. So if I call free like so: free(todos); it will free the whole block of memory for all my todo structs right?
@user2403221 yes, that is an accurate.
2

A little bit of background to Some programmer dude's answer

C11 standard, 7.22.3.3 "The free function", paragraph 2:

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

[emphasis by me]

Background (second level...) is that typically, you did not only receive the memory starting at the pointer, but additionally there is some kind of (machine/OS specific) control block right before the pointer's address that is needed to free the memory again.

You might try to peek at this control block by reading some bytes right before the pointer (just out of curiosity), but be aware that this actually is undefined behaviour as well (so don't ever do this in production code!) and might lead to your programme crashing.

answered Aug 1, 2018 at 15:32

Comments

0

As a reference, always that you do:

WhateverTypeInTheWorld *var1 = malloc(whateveryouwanttocompletearray);

then, you have to do

free(var1); /* use the same value you received from malloc() */

to return the memory back... as you did only one malloc(), you can do only one free() and pass to it the same pointer you got from malloc().

When you write:

free(&todos[i].i);

you are passing free the i-esim element field i's address, and not the pointer you received from malloc(). Probably you understood that you can free part of the memory you received... but it doesn't work that way... you get the memory in chunks, and you have to return it in those same chunks you received from malloc.

answered Aug 3, 2018 at 7:41

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.