How does free() affect the memory address on the heap?
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
This assignment asks us to allocate two int-type variables using malloc()
(named var1
and var2
), print the addresses of each variable (the address of the pointer on the stack and the address on the heap), then use free()
to deallocate var1
, print the addresses again, then allocate another space in the heap for var1
and print the addresses a third time. I believe that the instructor is trying to show us that the heap address for var1
is supposed to change, but it always stays the same... unless I remove free(var1)
from the code. The instructor did a similar demonstration, but did not use free()
to deallocate any variables, so we never saw how this was supposed to work.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void main()
int *var1 = (int*)malloc(sizeof(int));
*var1 = 1000;
int *var2 = (int*)malloc(sizeof(int));
*var2 = 2000;
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
free(var1);
printf("AFTER DEALLOCATING var1 FROM THE HEAPn");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
var1 = (int*) malloc(sizeof(int));
*var1 = 1500;
printf("NEW MEMORY ADDRESS ALLOCATED FOR var1n");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
This code results in this output:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
As you can see, the heap address does not change for var1
when I deallocate it, and it doesn't change when I allocate memory space for var1
again. However, if I simply remove the free(var1)
line from the program, it simply assigns a second memory space for var1
and points to that on the heap, which DOES have a different memory address:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000420
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
(Just to be clear, all I did was remove free(var1)
from the previous code, so the "AFTER DEALLOCATING var1" section now shows the exact same heap address as the previous set, but it DOES change the heap address of var1 in the third section.)
Can anybody tell me what is happening here? The only logical explanation I can come up with is that when I'm using free()
to deallocate var1
and then printing the address, it's simply printing the LAST address that it pointed to, and then when I'm allocating memory for var1
the second time, it's simply "backfilling" the previous address with the new value of var1
. Does this make sense? Do I have errors in my code, or is this just how C behaves when deallocating memory for a variable and then reallocating it?
c malloc heap-memory free memory-address
New contributor
add a comment |Â
up vote
7
down vote
favorite
This assignment asks us to allocate two int-type variables using malloc()
(named var1
and var2
), print the addresses of each variable (the address of the pointer on the stack and the address on the heap), then use free()
to deallocate var1
, print the addresses again, then allocate another space in the heap for var1
and print the addresses a third time. I believe that the instructor is trying to show us that the heap address for var1
is supposed to change, but it always stays the same... unless I remove free(var1)
from the code. The instructor did a similar demonstration, but did not use free()
to deallocate any variables, so we never saw how this was supposed to work.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void main()
int *var1 = (int*)malloc(sizeof(int));
*var1 = 1000;
int *var2 = (int*)malloc(sizeof(int));
*var2 = 2000;
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
free(var1);
printf("AFTER DEALLOCATING var1 FROM THE HEAPn");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
var1 = (int*) malloc(sizeof(int));
*var1 = 1500;
printf("NEW MEMORY ADDRESS ALLOCATED FOR var1n");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
This code results in this output:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
As you can see, the heap address does not change for var1
when I deallocate it, and it doesn't change when I allocate memory space for var1
again. However, if I simply remove the free(var1)
line from the program, it simply assigns a second memory space for var1
and points to that on the heap, which DOES have a different memory address:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000420
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
(Just to be clear, all I did was remove free(var1)
from the previous code, so the "AFTER DEALLOCATING var1" section now shows the exact same heap address as the previous set, but it DOES change the heap address of var1 in the third section.)
Can anybody tell me what is happening here? The only logical explanation I can come up with is that when I'm using free()
to deallocate var1
and then printing the address, it's simply printing the LAST address that it pointed to, and then when I'm allocating memory for var1
the second time, it's simply "backfilling" the previous address with the new value of var1
. Does this make sense? Do I have errors in my code, or is this just how C behaves when deallocating memory for a variable and then reallocating it?
c malloc heap-memory free memory-address
New contributor
1
1.free()
takes a pointer which you might provide with a variable. However, it doesn't change the contents of that variable. (Pointer is given by value tofree()
.) 2. If youfree()
N bytes and later (rather immediately)malloc()
N bytes again, why shouldn't you get the same address? Sounds, like heap management does a good job - it is re-using the free space of sufficient size. ;-)
â Scheff
7 hours ago
2
It makes perfect sense for amalloc
implementation to reuse space for a new object of the same size.
â John Bode
7 hours ago
Hey there. Not what you asking, but you don't need to cast the return value of malloc anymore. Also, I find useful to useint *var = malloc(sizeof *var)
instead ofint *var = malloc(sizeof(int))
. That way I can change the type ofvar
without the risk of forgetting to change it inside the malloc call (e.g.float *var = malloc(sizeof(int))
).
â ddz
6 hours ago
You're basically right. The lesson here is that, even after freeing memory, you may still have variables pointing to that memory, despite the fact that you don't own it. These "dangling pointers" can cause lots of misery, and that's why it's considered good practice to clear such pointers, e.g.free(p);p=NULL;
â Tim Randall
4 hours ago
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
This assignment asks us to allocate two int-type variables using malloc()
(named var1
and var2
), print the addresses of each variable (the address of the pointer on the stack and the address on the heap), then use free()
to deallocate var1
, print the addresses again, then allocate another space in the heap for var1
and print the addresses a third time. I believe that the instructor is trying to show us that the heap address for var1
is supposed to change, but it always stays the same... unless I remove free(var1)
from the code. The instructor did a similar demonstration, but did not use free()
to deallocate any variables, so we never saw how this was supposed to work.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void main()
int *var1 = (int*)malloc(sizeof(int));
*var1 = 1000;
int *var2 = (int*)malloc(sizeof(int));
*var2 = 2000;
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
free(var1);
printf("AFTER DEALLOCATING var1 FROM THE HEAPn");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
var1 = (int*) malloc(sizeof(int));
*var1 = 1500;
printf("NEW MEMORY ADDRESS ALLOCATED FOR var1n");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
This code results in this output:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
As you can see, the heap address does not change for var1
when I deallocate it, and it doesn't change when I allocate memory space for var1
again. However, if I simply remove the free(var1)
line from the program, it simply assigns a second memory space for var1
and points to that on the heap, which DOES have a different memory address:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000420
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
(Just to be clear, all I did was remove free(var1)
from the previous code, so the "AFTER DEALLOCATING var1" section now shows the exact same heap address as the previous set, but it DOES change the heap address of var1 in the third section.)
Can anybody tell me what is happening here? The only logical explanation I can come up with is that when I'm using free()
to deallocate var1
and then printing the address, it's simply printing the LAST address that it pointed to, and then when I'm allocating memory for var1
the second time, it's simply "backfilling" the previous address with the new value of var1
. Does this make sense? Do I have errors in my code, or is this just how C behaves when deallocating memory for a variable and then reallocating it?
c malloc heap-memory free memory-address
New contributor
This assignment asks us to allocate two int-type variables using malloc()
(named var1
and var2
), print the addresses of each variable (the address of the pointer on the stack and the address on the heap), then use free()
to deallocate var1
, print the addresses again, then allocate another space in the heap for var1
and print the addresses a third time. I believe that the instructor is trying to show us that the heap address for var1
is supposed to change, but it always stays the same... unless I remove free(var1)
from the code. The instructor did a similar demonstration, but did not use free()
to deallocate any variables, so we never saw how this was supposed to work.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void main()
int *var1 = (int*)malloc(sizeof(int));
*var1 = 1000;
int *var2 = (int*)malloc(sizeof(int));
*var2 = 2000;
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
free(var1);
printf("AFTER DEALLOCATING var1 FROM THE HEAPn");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
var1 = (int*) malloc(sizeof(int));
*var1 = 1500;
printf("NEW MEMORY ADDRESS ALLOCATED FOR var1n");
printf("Addresses of var1n");
printf("Pointer on stack: %p / Heap: %pnn", &var1, var1);
printf("Addresses of var2n");
printf("Pointer on stack: %p / Heap: %pnn", &var2, var2);
This code results in this output:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
As you can see, the heap address does not change for var1
when I deallocate it, and it doesn't change when I allocate memory space for var1
again. However, if I simply remove the free(var1)
line from the program, it simply assigns a second memory space for var1
and points to that on the heap, which DOES have a different memory address:
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
AFTER DEALLOCATING var1 FROM THE HEAP
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000390
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
NEW MEMORY ADDRESS ALLOCATED FOR var1
Addresses of var1
Pointer on stack: 0xffffcbf8 / Heap: 0x600000420
Addresses of var2
Pointer on stack: 0xffffcbf0 / Heap: 0x6000003b0
(Just to be clear, all I did was remove free(var1)
from the previous code, so the "AFTER DEALLOCATING var1" section now shows the exact same heap address as the previous set, but it DOES change the heap address of var1 in the third section.)
Can anybody tell me what is happening here? The only logical explanation I can come up with is that when I'm using free()
to deallocate var1
and then printing the address, it's simply printing the LAST address that it pointed to, and then when I'm allocating memory for var1
the second time, it's simply "backfilling" the previous address with the new value of var1
. Does this make sense? Do I have errors in my code, or is this just how C behaves when deallocating memory for a variable and then reallocating it?
c malloc heap-memory free memory-address
c malloc heap-memory free memory-address
New contributor
New contributor
edited 15 mins ago
Mat
162k27304335
162k27304335
New contributor
asked 7 hours ago
Firelion
361
361
New contributor
New contributor
1
1.free()
takes a pointer which you might provide with a variable. However, it doesn't change the contents of that variable. (Pointer is given by value tofree()
.) 2. If youfree()
N bytes and later (rather immediately)malloc()
N bytes again, why shouldn't you get the same address? Sounds, like heap management does a good job - it is re-using the free space of sufficient size. ;-)
â Scheff
7 hours ago
2
It makes perfect sense for amalloc
implementation to reuse space for a new object of the same size.
â John Bode
7 hours ago
Hey there. Not what you asking, but you don't need to cast the return value of malloc anymore. Also, I find useful to useint *var = malloc(sizeof *var)
instead ofint *var = malloc(sizeof(int))
. That way I can change the type ofvar
without the risk of forgetting to change it inside the malloc call (e.g.float *var = malloc(sizeof(int))
).
â ddz
6 hours ago
You're basically right. The lesson here is that, even after freeing memory, you may still have variables pointing to that memory, despite the fact that you don't own it. These "dangling pointers" can cause lots of misery, and that's why it's considered good practice to clear such pointers, e.g.free(p);p=NULL;
â Tim Randall
4 hours ago
add a comment |Â
1
1.free()
takes a pointer which you might provide with a variable. However, it doesn't change the contents of that variable. (Pointer is given by value tofree()
.) 2. If youfree()
N bytes and later (rather immediately)malloc()
N bytes again, why shouldn't you get the same address? Sounds, like heap management does a good job - it is re-using the free space of sufficient size. ;-)
â Scheff
7 hours ago
2
It makes perfect sense for amalloc
implementation to reuse space for a new object of the same size.
â John Bode
7 hours ago
Hey there. Not what you asking, but you don't need to cast the return value of malloc anymore. Also, I find useful to useint *var = malloc(sizeof *var)
instead ofint *var = malloc(sizeof(int))
. That way I can change the type ofvar
without the risk of forgetting to change it inside the malloc call (e.g.float *var = malloc(sizeof(int))
).
â ddz
6 hours ago
You're basically right. The lesson here is that, even after freeing memory, you may still have variables pointing to that memory, despite the fact that you don't own it. These "dangling pointers" can cause lots of misery, and that's why it's considered good practice to clear such pointers, e.g.free(p);p=NULL;
â Tim Randall
4 hours ago
1
1
1.
free()
takes a pointer which you might provide with a variable. However, it doesn't change the contents of that variable. (Pointer is given by value to free()
.) 2. If you free()
N bytes and later (rather immediately) malloc()
N bytes again, why shouldn't you get the same address? Sounds, like heap management does a good job - it is re-using the free space of sufficient size. ;-)â Scheff
7 hours ago
1.
free()
takes a pointer which you might provide with a variable. However, it doesn't change the contents of that variable. (Pointer is given by value to free()
.) 2. If you free()
N bytes and later (rather immediately) malloc()
N bytes again, why shouldn't you get the same address? Sounds, like heap management does a good job - it is re-using the free space of sufficient size. ;-)â Scheff
7 hours ago
2
2
It makes perfect sense for a
malloc
implementation to reuse space for a new object of the same size.â John Bode
7 hours ago
It makes perfect sense for a
malloc
implementation to reuse space for a new object of the same size.â John Bode
7 hours ago
Hey there. Not what you asking, but you don't need to cast the return value of malloc anymore. Also, I find useful to use
int *var = malloc(sizeof *var)
instead of int *var = malloc(sizeof(int))
. That way I can change the type of var
without the risk of forgetting to change it inside the malloc call (e.g. float *var = malloc(sizeof(int))
).â ddz
6 hours ago
Hey there. Not what you asking, but you don't need to cast the return value of malloc anymore. Also, I find useful to use
int *var = malloc(sizeof *var)
instead of int *var = malloc(sizeof(int))
. That way I can change the type of var
without the risk of forgetting to change it inside the malloc call (e.g. float *var = malloc(sizeof(int))
).â ddz
6 hours ago
You're basically right. The lesson here is that, even after freeing memory, you may still have variables pointing to that memory, despite the fact that you don't own it. These "dangling pointers" can cause lots of misery, and that's why it's considered good practice to clear such pointers, e.g.
free(p);p=NULL;
â Tim Randall
4 hours ago
You're basically right. The lesson here is that, even after freeing memory, you may still have variables pointing to that memory, despite the fact that you don't own it. These "dangling pointers" can cause lots of misery, and that's why it's considered good practice to clear such pointers, e.g.
free(p);p=NULL;
â Tim Randall
4 hours ago
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
9
down vote
It is perfectly normal that malloc
might return the same addresses when memory is freed and then reallocated. It would also be normal for it to return different addresses.
If you change the malloc
calls to request different sizes than the original allocations, you might get different addresses, since the old blocks malloc
had prepared might not be enough for the new requests. But they might be enough, so the addresses might not change.
Incidentally:
void main()
is incorrect. It should beint main(void)
.- Printing an address after the space it points to has been freed is not supported by the C standard. It is not uncommon for it to âÂÂwork,â but it is not proper. C 2018 6.2.4 2 tells us âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.â When an object allocated with
malloc
is freed withfree
, its lifetime ends.
Printing an address after the space it points to has been freed... Can't you print any address (as long as you don't access contents if it's not a valid address)?
â Scheff
7 hours ago
@Scheff: No. The C standard does not require pointers to be simply numeric addresses in a flat address space. Some C implementations use complicated addressing schemes (e.g,, segment and offset, and there are others), and these might require part of a pointer to be âÂÂactiveâ in that it refers to some other address or register or structure that is dynamically set up. When space is freed, that other information may be deconstructed. Then, whenprintf
attempts to format the pointer for%p
, its attempt to use that information may fail.
â Eric Postpischil
6 hours ago
Thanks. I find this is an interesting point worth to be mentioned in your answer. It's a bit beyond "it's just a value that can be printed" and interesting for whom which are used to flat addresses without harm. (Segment/offset addressing reminds me to the ancient DOS on 8086 but even in that case, I cannot remember that printing an invalid address was anyhow dangerous.)
â Scheff
6 hours ago
add a comment |Â
up vote
4
down vote
In the first example, the value of where the pointer used to point at the heap remains untouched at the stack after free()
. But you can no longer access that address.
When they allocate the variable yet again, it is not strange that you get the same address, as there should be an available segment of the right size at that address. You are however not guaranteed to get the same one - which address that's the best pick from what's available is handled by the library code.
add a comment |Â
up vote
3
down vote
The only logical explanation I can come up with is that when I'm using free() to deallocate var1 and then printing the address, it's simply printing the LAST address that it pointed to
Kind of right. Freeing a pointer does not affect the content of the pointer at all. Or to be more precise, it's value is indeterminate after being freed. In fact, according to the standard you cannot even trust the pointer to contain the address it did before invoking free
. As far as I know, it will in most cases, but you cannot trust it.
The standard says:
C 2018 6.2.4 2: âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.âÂÂ
A common mistake is to use the test if(ptr == NULL)
as a check if you have properly freed the pointer. This will not work.
3
The C standard does not guarantee that âÂÂFreeing a pointer does not affect the content of the pointer at all.â After a pointer is passed tofree
, using its value has unspecified behavior.
â Eric Postpischil
7 hours ago
@EricPostpischil but how canfree(pointer)
change the value ofpointer
? Sure after freeing, that value is meaningless, but the bit pattern ofpointer
will remain. After allfree
is just a function call. But, yes, I can't think of a use case where that meaningless value could be used for anything useful.
â Jabberwocky
7 hours ago
@EricPostpischilfree
can't change the value of the pointer passed to it though. So it will remain the same value as it was before, previously valid and with no trap representations. The contents of that address can of course no longer be accessed, but that's another story. This appears to be yet another error in informative Annex J of the standard. There is no normative text saying that the pointer takes an indeterminate value or some such.
â Lundin
6 hours ago
@Jabberwocky:free
cannot change the bytes that representpointer
, but it can change data structures that are used to organize memory and addressing. See my comment on my answer.
â Eric Postpischil
6 hours ago
@EricPostpischil Ah yeah you are correct, I read that wrong. You should add the quote to your answer.
â Lundin
6 hours ago
 |Â
show 1 more comment
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
9
down vote
It is perfectly normal that malloc
might return the same addresses when memory is freed and then reallocated. It would also be normal for it to return different addresses.
If you change the malloc
calls to request different sizes than the original allocations, you might get different addresses, since the old blocks malloc
had prepared might not be enough for the new requests. But they might be enough, so the addresses might not change.
Incidentally:
void main()
is incorrect. It should beint main(void)
.- Printing an address after the space it points to has been freed is not supported by the C standard. It is not uncommon for it to âÂÂwork,â but it is not proper. C 2018 6.2.4 2 tells us âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.â When an object allocated with
malloc
is freed withfree
, its lifetime ends.
Printing an address after the space it points to has been freed... Can't you print any address (as long as you don't access contents if it's not a valid address)?
â Scheff
7 hours ago
@Scheff: No. The C standard does not require pointers to be simply numeric addresses in a flat address space. Some C implementations use complicated addressing schemes (e.g,, segment and offset, and there are others), and these might require part of a pointer to be âÂÂactiveâ in that it refers to some other address or register or structure that is dynamically set up. When space is freed, that other information may be deconstructed. Then, whenprintf
attempts to format the pointer for%p
, its attempt to use that information may fail.
â Eric Postpischil
6 hours ago
Thanks. I find this is an interesting point worth to be mentioned in your answer. It's a bit beyond "it's just a value that can be printed" and interesting for whom which are used to flat addresses without harm. (Segment/offset addressing reminds me to the ancient DOS on 8086 but even in that case, I cannot remember that printing an invalid address was anyhow dangerous.)
â Scheff
6 hours ago
add a comment |Â
up vote
9
down vote
It is perfectly normal that malloc
might return the same addresses when memory is freed and then reallocated. It would also be normal for it to return different addresses.
If you change the malloc
calls to request different sizes than the original allocations, you might get different addresses, since the old blocks malloc
had prepared might not be enough for the new requests. But they might be enough, so the addresses might not change.
Incidentally:
void main()
is incorrect. It should beint main(void)
.- Printing an address after the space it points to has been freed is not supported by the C standard. It is not uncommon for it to âÂÂwork,â but it is not proper. C 2018 6.2.4 2 tells us âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.â When an object allocated with
malloc
is freed withfree
, its lifetime ends.
Printing an address after the space it points to has been freed... Can't you print any address (as long as you don't access contents if it's not a valid address)?
â Scheff
7 hours ago
@Scheff: No. The C standard does not require pointers to be simply numeric addresses in a flat address space. Some C implementations use complicated addressing schemes (e.g,, segment and offset, and there are others), and these might require part of a pointer to be âÂÂactiveâ in that it refers to some other address or register or structure that is dynamically set up. When space is freed, that other information may be deconstructed. Then, whenprintf
attempts to format the pointer for%p
, its attempt to use that information may fail.
â Eric Postpischil
6 hours ago
Thanks. I find this is an interesting point worth to be mentioned in your answer. It's a bit beyond "it's just a value that can be printed" and interesting for whom which are used to flat addresses without harm. (Segment/offset addressing reminds me to the ancient DOS on 8086 but even in that case, I cannot remember that printing an invalid address was anyhow dangerous.)
â Scheff
6 hours ago
add a comment |Â
up vote
9
down vote
up vote
9
down vote
It is perfectly normal that malloc
might return the same addresses when memory is freed and then reallocated. It would also be normal for it to return different addresses.
If you change the malloc
calls to request different sizes than the original allocations, you might get different addresses, since the old blocks malloc
had prepared might not be enough for the new requests. But they might be enough, so the addresses might not change.
Incidentally:
void main()
is incorrect. It should beint main(void)
.- Printing an address after the space it points to has been freed is not supported by the C standard. It is not uncommon for it to âÂÂwork,â but it is not proper. C 2018 6.2.4 2 tells us âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.â When an object allocated with
malloc
is freed withfree
, its lifetime ends.
It is perfectly normal that malloc
might return the same addresses when memory is freed and then reallocated. It would also be normal for it to return different addresses.
If you change the malloc
calls to request different sizes than the original allocations, you might get different addresses, since the old blocks malloc
had prepared might not be enough for the new requests. But they might be enough, so the addresses might not change.
Incidentally:
void main()
is incorrect. It should beint main(void)
.- Printing an address after the space it points to has been freed is not supported by the C standard. It is not uncommon for it to âÂÂwork,â but it is not proper. C 2018 6.2.4 2 tells us âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.â When an object allocated with
malloc
is freed withfree
, its lifetime ends.
edited 6 hours ago
answered 7 hours ago
Eric Postpischil
67.3k873146
67.3k873146
Printing an address after the space it points to has been freed... Can't you print any address (as long as you don't access contents if it's not a valid address)?
â Scheff
7 hours ago
@Scheff: No. The C standard does not require pointers to be simply numeric addresses in a flat address space. Some C implementations use complicated addressing schemes (e.g,, segment and offset, and there are others), and these might require part of a pointer to be âÂÂactiveâ in that it refers to some other address or register or structure that is dynamically set up. When space is freed, that other information may be deconstructed. Then, whenprintf
attempts to format the pointer for%p
, its attempt to use that information may fail.
â Eric Postpischil
6 hours ago
Thanks. I find this is an interesting point worth to be mentioned in your answer. It's a bit beyond "it's just a value that can be printed" and interesting for whom which are used to flat addresses without harm. (Segment/offset addressing reminds me to the ancient DOS on 8086 but even in that case, I cannot remember that printing an invalid address was anyhow dangerous.)
â Scheff
6 hours ago
add a comment |Â
Printing an address after the space it points to has been freed... Can't you print any address (as long as you don't access contents if it's not a valid address)?
â Scheff
7 hours ago
@Scheff: No. The C standard does not require pointers to be simply numeric addresses in a flat address space. Some C implementations use complicated addressing schemes (e.g,, segment and offset, and there are others), and these might require part of a pointer to be âÂÂactiveâ in that it refers to some other address or register or structure that is dynamically set up. When space is freed, that other information may be deconstructed. Then, whenprintf
attempts to format the pointer for%p
, its attempt to use that information may fail.
â Eric Postpischil
6 hours ago
Thanks. I find this is an interesting point worth to be mentioned in your answer. It's a bit beyond "it's just a value that can be printed" and interesting for whom which are used to flat addresses without harm. (Segment/offset addressing reminds me to the ancient DOS on 8086 but even in that case, I cannot remember that printing an invalid address was anyhow dangerous.)
â Scheff
6 hours ago
Printing an address after the space it points to has been freed... Can't you print any address (as long as you don't access contents if it's not a valid address)?
â Scheff
7 hours ago
Printing an address after the space it points to has been freed... Can't you print any address (as long as you don't access contents if it's not a valid address)?
â Scheff
7 hours ago
@Scheff: No. The C standard does not require pointers to be simply numeric addresses in a flat address space. Some C implementations use complicated addressing schemes (e.g,, segment and offset, and there are others), and these might require part of a pointer to be âÂÂactiveâ in that it refers to some other address or register or structure that is dynamically set up. When space is freed, that other information may be deconstructed. Then, when
printf
attempts to format the pointer for %p
, its attempt to use that information may fail.â Eric Postpischil
6 hours ago
@Scheff: No. The C standard does not require pointers to be simply numeric addresses in a flat address space. Some C implementations use complicated addressing schemes (e.g,, segment and offset, and there are others), and these might require part of a pointer to be âÂÂactiveâ in that it refers to some other address or register or structure that is dynamically set up. When space is freed, that other information may be deconstructed. Then, when
printf
attempts to format the pointer for %p
, its attempt to use that information may fail.â Eric Postpischil
6 hours ago
Thanks. I find this is an interesting point worth to be mentioned in your answer. It's a bit beyond "it's just a value that can be printed" and interesting for whom which are used to flat addresses without harm. (Segment/offset addressing reminds me to the ancient DOS on 8086 but even in that case, I cannot remember that printing an invalid address was anyhow dangerous.)
â Scheff
6 hours ago
Thanks. I find this is an interesting point worth to be mentioned in your answer. It's a bit beyond "it's just a value that can be printed" and interesting for whom which are used to flat addresses without harm. (Segment/offset addressing reminds me to the ancient DOS on 8086 but even in that case, I cannot remember that printing an invalid address was anyhow dangerous.)
â Scheff
6 hours ago
add a comment |Â
up vote
4
down vote
In the first example, the value of where the pointer used to point at the heap remains untouched at the stack after free()
. But you can no longer access that address.
When they allocate the variable yet again, it is not strange that you get the same address, as there should be an available segment of the right size at that address. You are however not guaranteed to get the same one - which address that's the best pick from what's available is handled by the library code.
add a comment |Â
up vote
4
down vote
In the first example, the value of where the pointer used to point at the heap remains untouched at the stack after free()
. But you can no longer access that address.
When they allocate the variable yet again, it is not strange that you get the same address, as there should be an available segment of the right size at that address. You are however not guaranteed to get the same one - which address that's the best pick from what's available is handled by the library code.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
In the first example, the value of where the pointer used to point at the heap remains untouched at the stack after free()
. But you can no longer access that address.
When they allocate the variable yet again, it is not strange that you get the same address, as there should be an available segment of the right size at that address. You are however not guaranteed to get the same one - which address that's the best pick from what's available is handled by the library code.
In the first example, the value of where the pointer used to point at the heap remains untouched at the stack after free()
. But you can no longer access that address.
When they allocate the variable yet again, it is not strange that you get the same address, as there should be an available segment of the right size at that address. You are however not guaranteed to get the same one - which address that's the best pick from what's available is handled by the library code.
answered 7 hours ago
Lundin
103k16151255
103k16151255
add a comment |Â
add a comment |Â
up vote
3
down vote
The only logical explanation I can come up with is that when I'm using free() to deallocate var1 and then printing the address, it's simply printing the LAST address that it pointed to
Kind of right. Freeing a pointer does not affect the content of the pointer at all. Or to be more precise, it's value is indeterminate after being freed. In fact, according to the standard you cannot even trust the pointer to contain the address it did before invoking free
. As far as I know, it will in most cases, but you cannot trust it.
The standard says:
C 2018 6.2.4 2: âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.âÂÂ
A common mistake is to use the test if(ptr == NULL)
as a check if you have properly freed the pointer. This will not work.
3
The C standard does not guarantee that âÂÂFreeing a pointer does not affect the content of the pointer at all.â After a pointer is passed tofree
, using its value has unspecified behavior.
â Eric Postpischil
7 hours ago
@EricPostpischil but how canfree(pointer)
change the value ofpointer
? Sure after freeing, that value is meaningless, but the bit pattern ofpointer
will remain. After allfree
is just a function call. But, yes, I can't think of a use case where that meaningless value could be used for anything useful.
â Jabberwocky
7 hours ago
@EricPostpischilfree
can't change the value of the pointer passed to it though. So it will remain the same value as it was before, previously valid and with no trap representations. The contents of that address can of course no longer be accessed, but that's another story. This appears to be yet another error in informative Annex J of the standard. There is no normative text saying that the pointer takes an indeterminate value or some such.
â Lundin
6 hours ago
@Jabberwocky:free
cannot change the bytes that representpointer
, but it can change data structures that are used to organize memory and addressing. See my comment on my answer.
â Eric Postpischil
6 hours ago
@EricPostpischil Ah yeah you are correct, I read that wrong. You should add the quote to your answer.
â Lundin
6 hours ago
 |Â
show 1 more comment
up vote
3
down vote
The only logical explanation I can come up with is that when I'm using free() to deallocate var1 and then printing the address, it's simply printing the LAST address that it pointed to
Kind of right. Freeing a pointer does not affect the content of the pointer at all. Or to be more precise, it's value is indeterminate after being freed. In fact, according to the standard you cannot even trust the pointer to contain the address it did before invoking free
. As far as I know, it will in most cases, but you cannot trust it.
The standard says:
C 2018 6.2.4 2: âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.âÂÂ
A common mistake is to use the test if(ptr == NULL)
as a check if you have properly freed the pointer. This will not work.
3
The C standard does not guarantee that âÂÂFreeing a pointer does not affect the content of the pointer at all.â After a pointer is passed tofree
, using its value has unspecified behavior.
â Eric Postpischil
7 hours ago
@EricPostpischil but how canfree(pointer)
change the value ofpointer
? Sure after freeing, that value is meaningless, but the bit pattern ofpointer
will remain. After allfree
is just a function call. But, yes, I can't think of a use case where that meaningless value could be used for anything useful.
â Jabberwocky
7 hours ago
@EricPostpischilfree
can't change the value of the pointer passed to it though. So it will remain the same value as it was before, previously valid and with no trap representations. The contents of that address can of course no longer be accessed, but that's another story. This appears to be yet another error in informative Annex J of the standard. There is no normative text saying that the pointer takes an indeterminate value or some such.
â Lundin
6 hours ago
@Jabberwocky:free
cannot change the bytes that representpointer
, but it can change data structures that are used to organize memory and addressing. See my comment on my answer.
â Eric Postpischil
6 hours ago
@EricPostpischil Ah yeah you are correct, I read that wrong. You should add the quote to your answer.
â Lundin
6 hours ago
 |Â
show 1 more comment
up vote
3
down vote
up vote
3
down vote
The only logical explanation I can come up with is that when I'm using free() to deallocate var1 and then printing the address, it's simply printing the LAST address that it pointed to
Kind of right. Freeing a pointer does not affect the content of the pointer at all. Or to be more precise, it's value is indeterminate after being freed. In fact, according to the standard you cannot even trust the pointer to contain the address it did before invoking free
. As far as I know, it will in most cases, but you cannot trust it.
The standard says:
C 2018 6.2.4 2: âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.âÂÂ
A common mistake is to use the test if(ptr == NULL)
as a check if you have properly freed the pointer. This will not work.
The only logical explanation I can come up with is that when I'm using free() to deallocate var1 and then printing the address, it's simply printing the LAST address that it pointed to
Kind of right. Freeing a pointer does not affect the content of the pointer at all. Or to be more precise, it's value is indeterminate after being freed. In fact, according to the standard you cannot even trust the pointer to contain the address it did before invoking free
. As far as I know, it will in most cases, but you cannot trust it.
The standard says:
C 2018 6.2.4 2: âÂÂThe value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.âÂÂ
A common mistake is to use the test if(ptr == NULL)
as a check if you have properly freed the pointer. This will not work.
edited 6 hours ago
answered 7 hours ago
Broman
5,68892241
5,68892241
3
The C standard does not guarantee that âÂÂFreeing a pointer does not affect the content of the pointer at all.â After a pointer is passed tofree
, using its value has unspecified behavior.
â Eric Postpischil
7 hours ago
@EricPostpischil but how canfree(pointer)
change the value ofpointer
? Sure after freeing, that value is meaningless, but the bit pattern ofpointer
will remain. After allfree
is just a function call. But, yes, I can't think of a use case where that meaningless value could be used for anything useful.
â Jabberwocky
7 hours ago
@EricPostpischilfree
can't change the value of the pointer passed to it though. So it will remain the same value as it was before, previously valid and with no trap representations. The contents of that address can of course no longer be accessed, but that's another story. This appears to be yet another error in informative Annex J of the standard. There is no normative text saying that the pointer takes an indeterminate value or some such.
â Lundin
6 hours ago
@Jabberwocky:free
cannot change the bytes that representpointer
, but it can change data structures that are used to organize memory and addressing. See my comment on my answer.
â Eric Postpischil
6 hours ago
@EricPostpischil Ah yeah you are correct, I read that wrong. You should add the quote to your answer.
â Lundin
6 hours ago
 |Â
show 1 more comment
3
The C standard does not guarantee that âÂÂFreeing a pointer does not affect the content of the pointer at all.â After a pointer is passed tofree
, using its value has unspecified behavior.
â Eric Postpischil
7 hours ago
@EricPostpischil but how canfree(pointer)
change the value ofpointer
? Sure after freeing, that value is meaningless, but the bit pattern ofpointer
will remain. After allfree
is just a function call. But, yes, I can't think of a use case where that meaningless value could be used for anything useful.
â Jabberwocky
7 hours ago
@EricPostpischilfree
can't change the value of the pointer passed to it though. So it will remain the same value as it was before, previously valid and with no trap representations. The contents of that address can of course no longer be accessed, but that's another story. This appears to be yet another error in informative Annex J of the standard. There is no normative text saying that the pointer takes an indeterminate value or some such.
â Lundin
6 hours ago
@Jabberwocky:free
cannot change the bytes that representpointer
, but it can change data structures that are used to organize memory and addressing. See my comment on my answer.
â Eric Postpischil
6 hours ago
@EricPostpischil Ah yeah you are correct, I read that wrong. You should add the quote to your answer.
â Lundin
6 hours ago
3
3
The C standard does not guarantee that âÂÂFreeing a pointer does not affect the content of the pointer at all.â After a pointer is passed to
free
, using its value has unspecified behavior.â Eric Postpischil
7 hours ago
The C standard does not guarantee that âÂÂFreeing a pointer does not affect the content of the pointer at all.â After a pointer is passed to
free
, using its value has unspecified behavior.â Eric Postpischil
7 hours ago
@EricPostpischil but how can
free(pointer)
change the value of pointer
? Sure after freeing, that value is meaningless, but the bit pattern of pointer
will remain. After all free
is just a function call. But, yes, I can't think of a use case where that meaningless value could be used for anything useful.â Jabberwocky
7 hours ago
@EricPostpischil but how can
free(pointer)
change the value of pointer
? Sure after freeing, that value is meaningless, but the bit pattern of pointer
will remain. After all free
is just a function call. But, yes, I can't think of a use case where that meaningless value could be used for anything useful.â Jabberwocky
7 hours ago
@EricPostpischil
free
can't change the value of the pointer passed to it though. So it will remain the same value as it was before, previously valid and with no trap representations. The contents of that address can of course no longer be accessed, but that's another story. This appears to be yet another error in informative Annex J of the standard. There is no normative text saying that the pointer takes an indeterminate value or some such.â Lundin
6 hours ago
@EricPostpischil
free
can't change the value of the pointer passed to it though. So it will remain the same value as it was before, previously valid and with no trap representations. The contents of that address can of course no longer be accessed, but that's another story. This appears to be yet another error in informative Annex J of the standard. There is no normative text saying that the pointer takes an indeterminate value or some such.â Lundin
6 hours ago
@Jabberwocky:
free
cannot change the bytes that represent pointer
, but it can change data structures that are used to organize memory and addressing. See my comment on my answer.â Eric Postpischil
6 hours ago
@Jabberwocky:
free
cannot change the bytes that represent pointer
, but it can change data structures that are used to organize memory and addressing. See my comment on my answer.â Eric Postpischil
6 hours ago
@EricPostpischil Ah yeah you are correct, I read that wrong. You should add the quote to your answer.
â Lundin
6 hours ago
@EricPostpischil Ah yeah you are correct, I read that wrong. You should add the quote to your answer.
â Lundin
6 hours ago
 |Â
show 1 more comment
Firelion is a new contributor. Be nice, and check out our Code of Conduct.
Firelion is a new contributor. Be nice, and check out our Code of Conduct.
Firelion is a new contributor. Be nice, and check out our Code of Conduct.
Firelion is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52951210%2fhow-does-free-affect-the-memory-address-on-the-heap%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
1.
free()
takes a pointer which you might provide with a variable. However, it doesn't change the contents of that variable. (Pointer is given by value tofree()
.) 2. If youfree()
N bytes and later (rather immediately)malloc()
N bytes again, why shouldn't you get the same address? Sounds, like heap management does a good job - it is re-using the free space of sufficient size. ;-)â Scheff
7 hours ago
2
It makes perfect sense for a
malloc
implementation to reuse space for a new object of the same size.â John Bode
7 hours ago
Hey there. Not what you asking, but you don't need to cast the return value of malloc anymore. Also, I find useful to use
int *var = malloc(sizeof *var)
instead ofint *var = malloc(sizeof(int))
. That way I can change the type ofvar
without the risk of forgetting to change it inside the malloc call (e.g.float *var = malloc(sizeof(int))
).â ddz
6 hours ago
You're basically right. The lesson here is that, even after freeing memory, you may still have variables pointing to that memory, despite the fact that you don't own it. These "dangling pointers" can cause lots of misery, and that's why it's considered good practice to clear such pointers, e.g.
free(p);p=NULL;
â Tim Randall
4 hours ago