3
int main()
{
    int *ptr, **ptr1;
    ptr = (int*)malloc(sizeof(int));
    ptr1 = (int**)malloc(sizeof(int));
    free(ptr);
    *ptr = 12345;
    ptr1 = &ptr;

    //free(ptr);
    //**ptr1 = 23456;
    printf("%d \n", **ptr1);
    system("pause");
    return 0;
}

How does *ptr store the value 12345, when the memory has already been freed? So, now ptr should be pointing to garbage. Why is this happening?

Rasmi Ranjan Nayak
  • 11,510
  • 29
  • 82
  • 122
  • If you know that the behaviour is undefined, why did you expect a specific behaviour? You obviously expected something and got surprized. – sellibitze Sep 06 '12 at 09:24
  • You should set each pointer that has been passed to `free()` a new target value. If you don't have one, assigned NULL. – harper Sep 06 '12 at 09:24
  • It's not quite the same question but it's still pretty much answered by the top answer on this question http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – jcoder Sep 06 '12 at 09:30
  • i have also asked similar question http://stackoverflow.com/questions/7007133/how-free-works – Jeegar Patel Sep 06 '12 at 09:51

5 Answers5

8

This code is just so very wrong, on so many levels.

  1. Don't cast the return value from malloc() in C.
  2. You're allocating the wrong sizes; ptr1 needs sizeof *ptr1, not sizeof (int). It's a pointer!
  3. Remember that malloc() might fail. Check the return value before using it.
  4. Don't (just don't) access memory after you've free()d it. Undefined behavior.

Also, note that the pointer itself is not destroyed when you call free() on it; the thing that goes away is the memory the pointer refers to. So you can still store a pointer's worth of bits in the pointer itself, if you like. There are rarely cases when this is needed though, and care should be taken when/if you inspect the bits.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • 3
    @1. in all fairness, the question is also tagged C++. But then again, you wouldn't use `malloc` in C++. – Luchian Grigore Sep 06 '12 at 09:13
  • It is not correct to say “the thing that goes away is the memory the pointer refers to.” The thing that goes away is, essentially, your permission to use the memory. Nor is this a quibble; it goes to the core of the question: The questioner is confused that they are still able to use memory after it is freed. Telling them, incorrectly, that the memory goes away compounds this confusion: If the memory is gone, how can they use it? Telling them that the memory remains but that you should not use it, even though you can, answers the question. – Eric Postpischil Sep 06 '12 at 13:27
  • It boggles the mind that this answer has received up-votes, because not a single sentence in it answers the question. Items 1-3 are irrelevant to the behavior that puzzles the questioner. Item 4 says what not to do but does not explain how the questioner gets the results they observe. The sentence about the memory going away is false. The sentence about storing bits in the pointer is irrelevant because the value in question, 12345, is never stored in a pointer. Nothing in this answer explains the problem: You **can** store in freed space but **should not** because it may be reused. – Eric Postpischil Sep 06 '12 at 16:12
4

The pointer is freed, but it still points whereever it did when it was allocated. It is considered a serious programming error to do this. But the run time environment does not (normally) help identify or correct such errors.

Do not point the gun at yourself and pull the trigger!

wallyk
  • 56,922
  • 16
  • 83
  • 148
3

That's undefined behavior, anything can happen.

free(ptr);
*ptr = 12345;

Is illegal. It can crash or, if you're unlucky, it can appear to work, potentially hiding the problem until the software is shipped to a nuclear power plant. Although, if you're writing code like this, you're probably not working for such companies. :)

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
1

You seem not to understand undefined behaviour. Basically, the behaviour is undefined. It could do anything, including (but not limited to) the following:

  1. crash
  2. Do what you erroneously expected it to do
  3. Do what you told it to do, but without producing errors
  4. Start a game of tetris on your console
  5. reformat your hard drive

Accessing freed memory in general is likely (on most systems) to appear as though it has worked, whilst randomly corrupting data that some other part of the program thinks it owns (depending if there's been an alloc after the free).

Attempting to define undefined behaviour is putting you on a hiding to nothing. It's much better just not to do it in the first place.

Tom Tanner
  • 9,244
  • 3
  • 33
  • 61
0

free() releases the memory pointed to by *ptr but does not change the value of *ptr so if that value does not conflict with anything else it will still work, but the memory may be allocated by another process at random. Common practice is to do free(ptr); ptr = NULL to avoid accidental reuse of the memory without another malloc call.

Alec Danyshchuk
  • 307
  • 2
  • 12