Sunday, October 27, 2019

c - How does free() affect the memory address on the heap?



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 

#include

void main()
{

int *var1 = (int*)malloc(sizeof(int));
*var1 = 1000;
int *var2 = (int*)malloc(sizeof(int));
*var2 = 2000;


printf("Addresses of var1\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var1, var1);
printf("Addresses of var2\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var2, var2);

free(var1);

printf("AFTER DEALLOCATING var1 FROM THE HEAP\n");
printf("Addresses of var1\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var1, var1);

printf("Addresses of var2\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var2, var2);

var1 = (int*) malloc(sizeof(int));
*var1 = 1500;

printf("NEW MEMORY ADDRESS ALLOCATED FOR var1\n");
printf("Addresses of var1\n");
printf("Pointer on stack: %p / Heap: %p\n\n", &var1, var1);
printf("Addresses of var2\n");

printf("Pointer on stack: %p / Heap: %p\n\n", &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?


Answer



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 be int 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 with free, its lifetime ends.


No comments:

Post a Comment

hard drive - Leaving bad sectors in unformatted partition?

Laptop was acting really weird, and copy and seek times were really slow, so I decided to scan the hard drive surface. I have a couple hundr...