15

Is this legal to do? Can you assign ptr to something after it has been freed?

int * ptr = (int*) malloc(sizeof(int));
free(ptr);
ptr = (int *) malloc(sizeof(int));
alk
  • 69,737
  • 10
  • 105
  • 255
skmiley1
  • 249
  • 2
  • 11
  • 9
    Welcome to Stack Overflow! [Please see this discussion on why not to cast the return value of malloc() and family in C..](https://stackoverflow.com/q/605845/2173917) – Sourav Ghosh Aug 22 '17 at 06:20
  • 6
    Perhaps a language issue, but the code you show does *not* "*assign ptr to something**", but the other way round: It assigns something *to* `ptr`, namely twice the result of a call to `malloc()`. – alk Aug 22 '17 at 06:28

8 Answers8

27

You aren't reassigning the pointer after freeing it, you're just reusing the ptr variable. This is perfectly fine.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
7

First of all, as I mentioned in the comments, please see this discussion on why not to cast the return value of malloc() and family in C..

That said, yes, the (re)-assignment is fine here.

Actually, the question wording

Can you assign ptr to something after it has been freed?

should read

Can you assign ptr with something after it has been freed?

Guess what, the assignment without free-ing is also legal as per C, but it will create a memory leak as a side effect as the variable ptr was holding the return value of a memory allocator function and you need to free the memory once you're done using it. If, you re-assign the pointer without keeping a copy of the pointer, you'll lose the access to the memory allocated by allocator function and will have no ways to free() it.

In case the pointer was holding an address of statically allocated variable, you don't get to (nned to) free it and direct re-assignment is perfectly fine. think of this below snippet.

int x = 5, y = 10;
int * p = &x;
//do something with p
p = &y; //this is fine, just a re-assignment.
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
6

Yes. it is a valid in C language.

Related stack overflow question for more information: Reusing freed pointers in C

According to cwe.mitre.org:

In this scenario, the memory in question is allocated to another pointer validly at some point after it has been freed. The original pointer to the freed memory is used again and points to somewhere within the new allocation. As the data is changed, it corrupts the validly used memory; this induces undefined behavior in the process.

msc
  • 33,420
  • 29
  • 119
  • 214
  • 4
    Setting the pointer to NULL after `free` is complete irrelevant in this case. – Support Ukraine Aug 22 '17 at 07:17
  • 1
    @4386427 in this case yes, generally no. – unalignedmemoryaccess Aug 22 '17 at 07:24
  • 6
    That quotation doesn't really support your answer, and is really confusing as it's context is behind the link. I suggest you remove it. Also, please don't overuse emphasis as it makes text harder to read. – user694733 Aug 22 '17 at 07:31
  • 1
    'So, it is bad practice to reuse freed pointer' I disagree. There are times when it's very useful to 'reseat' a pointer variable, eg. when receiving a pointer popped from a producer-consumer queue or returned in an API callback - as long as those pointers are freed/released/deallocated/whatever after handling whatever they point to, that's just fine:) – Martin James Aug 22 '17 at 09:09
5

Is this legal to do? Can you assign ptr to something after it has been freed?

Yes, this is legal. ptr can be reassigned as many times as you want. Freeing that pointer is not necessary for reassigning it, for example

int * ptr = malloc(sizeof(int));
int *temp_ptr = ptr;         // temp_ptr is pointing to the location ptr is pointing
ptr = malloc(sizeof(int));   // ptr points to new location.

Note that you should not cast the return value of malloc.

haccks
  • 104,019
  • 25
  • 176
  • 264
5

Can you assign ptr to something after it has been freed?

int * ptr = (int*) malloc(sizeof(int)); /* line 1 */
free(ptr); /* line 2 */
ptr = (int *) malloc(sizeof(int)); /* line 3 */

Taking your question as:

"Is it legal to assign the address of freshly, dynamically allocated memory to a pointer (line 3), after the memory this pointer pointed to from a previous dynamical allocation (line 1) had been freed (line2)?"

Then this answer is yes.


Running line 3 would also be valid without having run line 2. Still, if not calling free() (line 2), the value assigned to ptr (line 1) is overwritten (line 3), and with this the possibility to call free() on ptr's initial value is lost, which in turn leaves the program with leaking exactly this memory allocated initially.

alk
  • 69,737
  • 10
  • 105
  • 255
3

Yes you are assigning new memory on heap and its legal.

I would recommend you use realloc instead.

For the case when realloc() fails, from , chapter §7.22.3.5,

The realloc function returns ... a null pointer if the new object could not be allocated.

and

[....] If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

The proper way of using realloc will be

ptr_new = realloc(ptr, sizeof(int)*2);
if (ptr_new == NULL)
{
    free(ptr);
}

Also please read why should i not cast return value of malloc.

kocica
  • 6,412
  • 2
  • 14
  • 35
  • "*I would recommend you use `realloc` instead.*" Why? This would depend on the context. Also recommending to call `free()` after a failed `realloc()` without any context might be taking wrong. And also might not be wanted. – alk Aug 22 '17 at 08:09
  • Becouse it seemed like he want change size of allocated memory. The freeing is explained. – kocica Aug 22 '17 at 08:14
3

Yes. It is perfectly legal. ptr is a standalone variable that continues to exist regardless of its contents. Nothing happens to the memory location where ptr is stored. There is nothing to prevent you from assigning you any value to it. The correctness of the memory allocation ( malloc / realloc etc) is a different story, but there is nothing wrong with reusing a variable (a memory location) to store the address of a memory location.

Raul Grigorașcu
  • 71
  • 1
  • 1
  • 5
2

When you declare a pointer it will be allocated for it a memory location. That location can be reassigned.

If you reassign it after having assigned it a value with a malloc() call and before to free() it, this is a memory leak. After free() you can reassign it and no leak will happen, do not forget to free() it again.

In fact, the operating systems that are useful programs that never finish will reassign all the time some fixed pointers toward processes, free them when the process finishes, etc.

The programming in which assignments are not allowed is called functional programming.

alinsoar
  • 15,386
  • 4
  • 57
  • 74