I had this same question. I proved to myself that you should definitely not use the pointer after its freed and does give undefined behavior. Sometimes it works, other times it does not work, and will crash in a strange way. Example is below.
#include <iostream>
#include <malloc.h>
int main()
{
int n = 100000;
float* testfree = (float*)malloc(sizeof(float) * n);
printf("test pointer address in direct free: %p\n", testfree);
for (int i = 0; i < n; i++)
testfree[i] = i * i;
int ind = 6;
printf("testfree[%d] = %f\n", ind, testfree[ind]);
system("pause");
free(testfree);
printf("test pointer address after free: %p\n", testfree);
printf("testfree[%d] = %f\n", ind, testfree[ind]);
return 42;
}
OUTPUT:
test pointer address in direct free: 000001D374F3E150
testfree[6] = 36.000000
Press any key to continue . . .
test pointer address after free: 000001D374F3E150
testfree[6] = 36.000000
C:\Users\ToshibaUser\source\repos\mallocfreereturn\x64\Release\mallocfreereturn.exe
(process 19652) exited with code 42.
Press any key to close this window . . .
This works every time for me, prints values and pointer address it had before the free().
When n = 1,000,000 or higher it crashes (I only tried multiples of 10, cant go higher than max for 32 bit integers also...) but, the crash point is confusing because, in my debugger in MSVS, the error location is at the free(),
if you comment out only this line
//printf("testfree[%d] = %f\n", ind, testfree[ind]);
it will not crash and will still get the right pointer address with really large values of n (at least 1,000,000).
Next thing I checked is freeing the pointer/block after it was allocated in a function with only the pointer returned. I did confirm it does exactly the same thing. malloc() only returns the pointer weather its in a different function or used directly, and its up to you to figure out what to do with defining what is in the block and remembering how big that block is. So this is not really any different. Actually, the memory chunk does contain extra info that is not visible to the developer, see references for deep dive. I had to make sure the memory is actually freed and doesn't take up RAM, because my application completely fills my RAM, and I do some calculations then I free some stuff, then I allocate different stuff. It's not that I have a lame computer, I have 128 GB of RAM, I'm doing scientific computing :)
Definitely the free() does free up the RAM but the memory still has the values you gave it because why clean your room until someones coming over?
THIS HAS EXACTLY THE SAME RESULTS:
#include <iostream>
#include <malloc.h>
float* mallocret(int n);
int main()
{
int n = 10000000000;
float* freeme = mallocret(n);
printf("returned pointer address outside function: %p\n", freeme);
int ind = 6;
printf("freeme[%d] = %f\n", ind, freeme[ind]);
system("pause");
free(freeme);
printf("returned pointer address outside function: %p\n", freeme);
printf("freeme[%d] = %f\n", ind, freeme[ind]);
return 42;
}
USING THIS FUNCTION DEFINED IN A SEPARATE FILE
#include <iostream>
#include <malloc.h>
float* mallocret(int n)
{
float* retp = (float*)malloc(sizeof(float) * n);
printf("return pointer address in function: %p\n", retp);
for (int i = 0; i < n; i++)
retp[i] = i*i;
return retp;
}
OUTPUT:
return pointer address in function: 00000297C1B4DF70
returned pointer address outside function: 00000297C1B4DF70
freeme[6] = 36.000000
Press any key to continue . . .
returned pointer address outside function: 00000297C1B4DF70
freeme[6] = 36.000000
C:\Users\ToshibaUser\source\repos\mallocfreereturn\x64\Release\mallocfreereturn.exe (process 8032) exited with code 42.
Press any key to close this window . . .
DONT USE THE POINTER AFTER ITS FREED! IT DOES NOT ALWAYS WORK!
note: always return 42 from main.
REFERENCES:
How does free know how much to free?
How do free and malloc work in C?
https://www.gnu.org/software/libc/manual/html_node/Freeing-after-Malloc.html
https://www.interviewsansar.com/how-does-free-know-amount-of-memory-to-deallocate/
https://www.geeksforgeeks.org/g-fact-88/
https://en.wikipedia.org/wiki/C_dynamic_memory_allocation
https://en.wikipedia.org/wiki/Cruft