1

I have an array-like structure made using singly-linked lists. If I want to remove a certain cell, do I have to free the pointer pointing to it row-wise and column-wise?

My structure looks like this:

S  -> C0 -> C1 -> C2 -> ...
       v     v     v
R0 -> 00 -> 01 -> 02 -> ...
       v     v     v
R1 -> 10 -> 11 -> 12 -> ...
       v     v     v 
R2 -> 20 -> 21 -> 22 -> ...

And say I want to remove 11 and relink. Do I have to free 11 using the pointer in 01 AND 10?

S  -> C0 -> C1 -> C2 -> ...
       v     v     v
R0 -> 00 -> 01 -> 02 -> ...
       v     v     v
R1 -> 10 ->->v->->12 -> ...
       v     v     v 
R2 -> 20 -> 21 -> 22 -> ...
user2154420
  • 442
  • 4
  • 17

2 Answers2

8

No, you don't "free the pointer", you free the memory the pointer is pointing at.

This should be pretty easy to understand, if you just think about it some more. Consider code like this, which is meant to be a simplified view of what you're asking:

void *ptr = malloc(1024); /* Allocate 1024 KB of memory, somewhere. */
void *copy1 = ptr;
void *copy2 = ptr;
void *copy3 = ptr;
void *copy4 = ptr;

When the above has run, assuming the allocation succeeds, we clearly have five pointers to the same block of memory. We can de-allocate the memory using any of the five pointers, since their values are identical:

free(ptr3); /* Any one would work. */

Of course, we can't call free() with more than one of the pointers, since all the pointers are pointing at the same block of memory.

You can only free a block of memory once, it's undefined behavior to call free() multiple times for the same address (unless you did a new allocation in-between of course).

This is of course explained in the manual page which you really should study:

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. If ptr is NULL, no operation is performed.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • I still remember my lecturer saying to always check, whether the pointer you are using free on, is actually NULL. This is easiest way to not get the double free problem. – Evdzhan Mustafa Oct 08 '14 at 12:18
  • @Theolodis That link is for C++. The example code also casts the returnvalue from malloc(). – wildplasser Oct 08 '14 at 12:18
  • 2
    @EvdzhanMustafa : not is is not. There could be two pointers pointing to the same object, like in this Question. – wildplasser Oct 08 '14 at 12:20
  • 3
    @EvdzhanMustafa No, that's just pointless and a sign that your lecturer is perhaps not 100% up to speed on these things. Protecting against `free(NULL)` of course also does *nothing* to protect against double-free. – unwind Oct 08 '14 at 12:26
  • @wildplasser `#include ` is obviously C. And it doesn't matter if the pointer is casted or not. – Theolodis Oct 08 '14 at 12:28
  • @Theolodis That it "doesn't matter" is [not something everybody would agree with](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – unwind Oct 08 '14 at 12:29
  • @unwind "In my opinion, it's a failure to include the cast, even if you got it right." consider the last part of the sentence. (from your cited source) Anyway, you seem to avoid explaining how I was wrong ;) specially considering your first comment. – Theolodis Oct 08 '14 at 12:35
  • @Theolodis Yes? I'm trying to say that even if the cast is technically correct, i.e. does the correct conversion of the pointer value, it's still more bad than good to have a cast there, since it a) can cause actual errors to be hidden (cast away), b) pointless in the first place. Code with the cast is worse than code without, thus it certainly matters (in my opinion). – unwind Oct 08 '14 at 12:38
  • @unwind ok, I accept your opinion. Personally I do not use C anyway, so I do not have any personal preferences considering that topic (I have seen both in production code, so that might be opinion-based only). But would you mind explain how my cited sources code is `c++` and not `c`? – Theolodis Oct 08 '14 at 12:46
  • @Theolodis I wasn't the one to claim your code was C++. But the domain itself of course hints at its focus, plus the use of casts such as those in that page's code often signals that the code is meant to be compiled as C++ (since in C the casts are not needed, and don't add any value so they're not recommended even though they would work). – unwind Oct 08 '14 at 12:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/62676/discussion-between-theolodis-and-unwind). – Theolodis Oct 08 '14 at 12:50
  • +1 for the first sentence. OP's understanding is due to bad books/teachers talking about "freeing pointers" rather than "freeing objects". – R.. GitHub STOP HELPING ICE Oct 08 '14 at 13:07
1

No, in fact you must not free the same object twice. If you have two pointers pointing to something, one way is to use "shared pointers" which do reference counting; another is to use raw pointers in your data structure and manage the lifetime of the objects elsewhere. Or in your particular case you could have some convention, such as that the pointer "above" is the owner and the one to the "left" is not.

Look up "double free" and you'll see what sort of error you'll have if you free both pointers.

By the way, if you free a null pointer, nothing is done, so one way to deal with this sort of thing is to always set your pointers to null after freeing them. In your case that would mean setting two pointers to null, of course, to avoid the possibility of double-free.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436