2

So I'm new to C and creating some simple programs to help me get a hang of things.

Let's say I have a struct as follows:

typedef struct {
   char* field;
} something;

And I dynamically allocate space for 10 of these as follows:

something* stuff = calloc(10, sizeof(something));

Let's say I then want to delete one of these somethings. Would it make sense to do:

free(&stuff[4]);

Or would that only make sense if I had made all of these pointers to somethings instead of a contiguous block of somethings?

If I did that and it worked, would:

stuff[4] = malloc(sizeof(something))

Then be all I need to re-add a "something" to that index?

Or, in general, do we usually deal with such structures as a block of memory that contains pointers to the structs, not the structs themselves?

Thanks.

OmG
  • 18,337
  • 10
  • 57
  • 90
Paul B
  • 349
  • 4
  • 14
  • Apart from the deallocation issue, `calloc` sets the allocated memory to all-bits-zero -- which does *not* necessarily set `field` to `NULL`. Null pointers are very commonly represented as all-bits-zero, but the language standard very carefully does not guarantee that. It's generally better to use `malloc` and just be careful not to access memory that you haven't initialized. – Keith Thompson Jul 02 '13 at 00:10

2 Answers2

8

The rule is very simple. You can and should free precisely that which you allocated. That is, you must only pass pointers to free() which you received as the return value of malloc/calloc/realloc etc.*, or a null pointer. Nothing else may be passed to free().

So, you can free tne entire array, or nothing at all.

(Note also that "freeing a single element from the middle" would be utterly pointless, because you would have no way of iterating over such a "holy" array sensibly.) If you want to deallocate some memory, allocate a new range, copy the desired elements over and free the original array.

*) Some quasi-standard functions may indirectly return dynamically allocated memory which you must fre; check the documentation. Some examples are strdup, GNU's scanf, and GCC's abi::__cxa_demangle.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Got it, thanks. So it really wouldn't make sense to even try to "delete" one of the "somethings" from the allocated space, right? The best I could really do is just clear the fields? – Paul B Jul 01 '13 at 23:44
  • @PaulBakoyiannis: It wouldn't make any sense whatsoever. Think about pointer arithmetic and how you address elements of the array. – Kerrek SB Jul 01 '13 at 23:45
  • Well, I can imagine a memory management system where it might make sense. After freeing a chunk of memory in the middle of the array, you'd still have the sub-arrays preceding and following the deletion, and the space occupied by the deleted element would be available for further allocation. But C doesn't support it. If you want to be able to delete elements like that, you probably want a linked list, not an array. – Keith Thompson Jul 02 '13 at 00:16
5

According to the man pages

The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs.

You can only free the whole block of data. So do not attempt to free anything else.

LostBoy
  • 948
  • 2
  • 9
  • 21