Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can still print a string after I freed it?

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);
like image 525
Peter Paul Avatar asked Jul 19 '17 18:07

Peter Paul


1 Answers

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.

like image 150
Iharob Al Asimi Avatar answered Sep 24 '22 00:09

Iharob Al Asimi