-2

Is there a difference between those two variants of calling free after allocating memory on the heap:

// variant 1
int* p1 = (int*) malloc(sizeof(int)*4);
free(p1);

//variant 2
int* p2 = (int*) malloc(sizeof(int)*4);
free(*p2);
*p2 = NULL;
trincot
  • 317,000
  • 35
  • 244
  • 286
clickMe
  • 993
  • 11
  • 33
  • 1
    only the pointer p1 or p2 is allocated and thus can be freed. Dereferencing the pointer with *p2 only gets you an instance within the allocated block. – kenny Sep 13 '15 at 17:49
  • You will only see the second variant when **the address** of `p2` is passed to a function (e.g. `some_func (int **p) {...}` and you call `some_func (&p2)`) Then within `some_func`, it would be valid to `free(*p);` – David C. Rankin Sep 13 '15 at 18:03

4 Answers4

6

Yes, there is a difference.

Variant 2 is invalid. free expects a pointer previously returned by malloc, calloc, or realloc. *p2 is the first int in the allocated space, though. As man free says, undefined behavior occurs therefore (quotation adjusted for this specific case):

free() function frees the memory space pointed to by [p1], which must have been returned by a previous call to malloc(), calloc(), or realloc(). Otherwise, [...] undefined behavior occurs.


Notes:

Community
  • 1
  • 1
cadaniluk
  • 15,027
  • 2
  • 39
  • 67
2

Yes. free(*p2) is invalid.

free frees the memory at the address it's given. Consider: what does p1 evaluate to? Its value is the pointer that malloc returned - so p1 evaluates to the pointer to the memory that malloc allocated.

What does *p2 evaluate to? Its value is the integer that is stored at the address of p2. This can be anything and it is very unlikely it'll be a valid pointer. Thus free will attempt to free an invalid memory address and you'll get a segfault if you're lucky.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
0

Yes, there's a difference. The first way, called on a pointer pointing to memory allocated by malloc is right. The second, calling a dereference of such a pointer, attempts to free some arbitrary memory address (with the value held in the value that pointer is pointing to), and is just wrong.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
0
free(p1);

This is valid as you allocate memory to p1 and then free, thus no problem.

free(*p2);

It is unlikely to be valid as *p2 may or may not be a valid pointer (which need to have an allocated memoty ).

using free() on a pointer which is not allcocated memory using malloc or similar will cause error.

ameyCU
  • 16,489
  • 2
  • 26
  • 41