问题
I am learning and testing memory allocation in C and I want to test what happens if free()
is called.
I expected there could be a segmentation fault or pointer is NULL
after I run the program below. However, I can still successfully print the string as in Output. I also tried to free str
twice, then an error as Output 2 occurred.
It seems the previously allocated memory is successfully deallocated, but the data on the memory is not cleaned up. Is that correct? If that is the case, when will the program clean up those deallocated memory space? Is that safe if the data is deallocated but not cleaned up?
Answers to any question above will be helpful! Thanks!
Code
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello, World!\n");
char *str = (char *)malloc(24);
char *str2 = "tutorialspoint";
strcpy(str, str2);
free(str);
printf("[str] %s\n", str);
return 0;
}
Output
Hello, World!
[str] tutorialspoint
Output 2
main(83218,0x7fff9d2aa3c0) malloc: *** error for object 0x7fb0b2d00000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Edit
Thank you all for helpful replies. Now I understand that there are some undefined behaviors (UB) in C and this helped me understand something else confused me before such as writing to a string beyond the scope of allocated(like what's in the code snippet below). This caused UB according to wiki, but the program will not crash.
Feel free to correct me if I got it wrong!
char *str = (char *)malloc(0);
char *str2 = "tutorialspoint";
strcat(str, str2);
printf("[str] %s, [addr] %p\n", str, str);
回答1:
You need to learn the concept of undefined behavior.
Even if you print the string after you free it and it "works", it doesn't mean it worked. It's just one of the things that can happen when the behavior is said to be undefined, which in this case it is.
Also, the pointer will not be NULL
except if you do this
free(ptr);
ptr = NULL;
and free()
, doesn't set all bytes to 0
either.
The free()
function just does exactly what it's name suggests. It allows malloc()
to use the free()
d chunk again. The data the pointer pointed to might still be there unchanged and that is the reason why you can still print the previous content after free()
. But there is absolutely no guarantee of what will happen if you do dereference a pointer after free()
or whether the data still exists or, was completely or partially overwritten.
If you do dereference the pointer after having free()
d it, there is one thing you do know, the behavior is undefined.
回答2:
When you call free
, it allows the pointed-to memory to be used for other purposes. Attempting to read or write memory that has been freed invokes undefined behavior.
Just because the memory has been given up doesn't necessarily mean it's been physically wiped.
An analogy: Suppose you left a book on your hotel room table. You check out of the hotel, but you still have the key card. If you go back to the room the book might be there, or it might not.
来源:https://stackoverflow.com/questions/45198752/can-still-print-a-string-after-i-freed-it