0

In the below code I free the pointer ptr but still *ptr retuns me the same value. If I free the variable then it should give me some garbage value but it didn't.

#include <stdio.h>
#include<stdlib.h>
int main()
{
    int a=5;
    int *ptr=&a;
    printf("%d, %d \n",a,*ptr);
    free(ptr);
    printf("%d, %d \n",a,*ptr);
    return 0;
}
user438383
  • 5,716
  • 8
  • 28
  • 43
  • 5
    [`free()`](https://en.cppreference.com/w/c/memory/free) is not for "freeing" pointers. It is for de-allocating memory that has been allocated using [`malloc()`](https://en.cppreference.com/w/c/memory/malloc) – Aziz Feb 18 '22 at 11:03
  • *"it should give me some garbage value"* - how do you know that the value you receive *isn't* a "garbage value"? – UnholySheep Feb 18 '22 at 11:04
  • @UnholySheep I declared varable a and assigned it a value of 5. and pointer ptr gave the addreass of a. So value recieved isn't different from a i.e.5. –  Feb 18 '22 at 11:08
  • `free` means you are returning the memory to the system and promising not to use it again. It does not say what the system will do with it. It certainly doesn't say the system has to put a "garbage" value in it. But you must not access freed memory. The result is Undefined Behaviour. UB means it can get a wrong value, it can crash, it can appear to "work" and any other unpredictable behaviour. – kaylum Feb 18 '22 at 11:09
  • Again, why do you think that 5 *isn't* a garbage value? There is no definition of a garbage value, so it might as well be the same value you read before – UnholySheep Feb 18 '22 at 11:10
  • @Aziz So,what's about this #include #include int main() { int *ptr=(int*)malloc(sizeof(int)); int a=10; ptr=&a; printf(" %d \n",*ptr); free(ptr); printf(" %d \n",*ptr); return 0; } It also returns me same value –  Feb 18 '22 at 11:11
  • @UnholySheep If it's garbage value then why I get same garbage value everytime whenever I run the program. –  Feb 18 '22 at 11:14
  • That doesn't prove anything. When your code invokes *undefined behavior* it might exhibit the same result every time. Or it might change depending on compiler versions/settings/some other random thing. Your code is broken and you can get any random combination of results – UnholySheep Feb 18 '22 at 11:16
  • @VishalMourya: You’re still doing the same thing as your original snippet, you’re assigning `ptr` to point to `a`, not to the memory you allocated with `malloc`. – John Bode Feb 18 '22 at 11:17

4 Answers4

2

You can only free memory that has been allocated by malloc, calloc, or realloc - you cannot use it to deallocate memory associated with an auto variable (the behavior is undefined):

int *ptr = malloc( sizeof *ptr );
*ptr = 5;
printf( "%d\n", *ptr );
free( ptr );
John Bode
  • 119,563
  • 19
  • 122
  • 198
2

If you haven't allocated the memory yourself as John Bode answered, you cannot free it.

But even if you did allocate the memory, the free does not erase the contents of the memory block pointed by your pointer, it merely allows that block of memory to be used by something else, hence it "frees" it, not "erase"s. If nothing else happens to write to that memory block after you freed it, your content will still be sitting there.

aulven
  • 521
  • 3
  • 14
  • 1
    No no no. Your answer was great until the last paragraph. But please do not recommend bogus practices that are no substitute for proper tools (such as ASan). – Konrad Rudolph Feb 18 '22 at 11:21
  • @KonradRudolph I thought that was "the" right practice, what's wrong with that? – aulven Feb 18 '22 at 11:29
  • 1
    It’s definitely not the right practice. Virtually nobody does that, because it doesn’t work: `int *x = malloc(*x); int *y = x; … free(x); x = NULL; *y;` opps, you assigned `NULL` to `x` but since `y` contained a copy of the pointer, accessing it is still not safe. No. The *real* way to save against such accesses is to use ASan or similar tools. – Konrad Rudolph Feb 18 '22 at 11:30
  • @KonradRudolph I see, I am removing that part from the answer. – aulven Feb 18 '22 at 11:32
  • Even without the intermediate pointer, assigning `NULL` is not guaranteed to help. When `*x` is used, the C standard allows the compiler to assume `x` is not a null pointer, even if it was assigned `NULL` in the immediately preceding value. This means an optimizer that has cached `x` in a register can use the cached value instead of a null pointer, so `*x` could behave as if `x` still pointed to the allocated memory. – Eric Postpischil Feb 18 '22 at 11:40
1

free(ptr) does not change the value of ptr. It merely asks the memory management software to release the reservation of the memory that ptr points to. Calling a function passes the value of its arguments; it does not pass any information about the identity of its arguments, so free does not receive any information about the ptr variable that would allow free to change that variable. It receives only a copy of its value.

Further, the behavior of free is defined only when it is passed an address that was previously returned by malloc or a related routine. It is not defined when given the address of a named object, such as &a.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

Two things:

First: the value ptr contains is not memory allocated with malloc.
For every malloc, there must be a free. Since you are free()ing memory you don't allocate with malloc, you are invoking Undefined Behaviour (C and C++ programmers love this term)

Second: Since you are invoking Undefined Behaviour, the behaviour can be anything. A seemingly correct behavouring program can be in the territory of undefined behaviour. You are simply lucky that you receive the same value over and over. On other systems your program could crash, kill an innocent grandma or simply push the delete button of the universe.

Raildex
  • 3,406
  • 1
  • 18
  • 42