struct node
{
unsignedchar g;
};
int main(void)
{
struct node* x = (node*)malloc(sizeof(struct node));
x->g = 2;
free(x);
x = NULL;
return 0;
}
Hello , I would like to ask about the free() function , while debugging I can see that the free(x) sets the unsigned char g to 0.
Question : It must be always like this ?
I'm asking this because I wrote a snippet where free doesn't set my tree node data to 0 but sets itself only to NULL.( In this case I'm not sure if free did his job , or I did mine wrong )
No. Usually in a release build, the value isn't changed. The block can be cleared by debug builds to catch bugs, but it takes time (and can cause page faults) and isn't necessary.
Calling free tells the compiler that you no longer need the memory that you once allocated and it can be put back into the free memory pool and can be allocated again by a subsequent malloc.
Whether the compiler zeroes out the memory or not is immaterial. If you freed the memory, you no longer care what values the memory holds. That is why you (correctly) assigned the value NULL to x after you freed x. You no longer care what is in the memory previously pointed to by x, so you overwrote the address with NULL.
Why do you care whether the memory is set back to 0 or not?
I cared about that unsigned char g in there , because I also have a binary tree implemented and when this, executes free(binary_tree_node) , it doesn't not set my data( int , double whatever ) in the binary_tree_node to 0 as opposed to the example above.
free() tells the program that the memory is no longer needed and is available for reuse by malloc() or realloc(). The details are completely up to library implementer. Some implementations may change the block, others may leave it unchanged. Some may change every other block that's freed, or every block that's adjacent to another free block, or every block that contains the word "hello" or every third block on the second Tuesday of the month....
The point is that you must consider the contents of the block undefined. You cannot rely on what's there and you cannot use it.
I cared about that unsigned char g in there , because I also have a binary tree implemented and when this, executes free(binary_tree_node) , it doesn't not set my data( int , double whatever ) in the binary_tree_node to 0 as opposed to the example above.
I still don't understand why you care about this. Data is a bunch of bits in memory. When it has been allocated as is being used in a meaningful manner, the bits have meaning. When you free it, it is no longer meaningful, and any apparent value in those bits is meaningless. Whether the bits contain the value that they last held before being freed, or they contain 0x00, or if they contain 0xFF, or any other value is not important because the memory is no longer valid. Any attempt to read that memory is dangerous. That is why the pointer to that memory should be set to NULL immediately after the free.
If you have a binary tree where a link to a child node is in question, that child node must be deallocated or reassigned before freeing the root node, because there will be no reliable way to reach the child node through the root node after the root node is freed. And if the data contains a pointer to other malloced memory, that memory has to be cleaned up properly so that a memory leak does not occur. But there is no reason to care whether freed memory is zeroed out or not.
Memory should only be freed when it is no longer needed. If you freed and and still cared about it then you shouldn't have freed it in the first place.
I suggest you re-examine the design of your code. You should never attempt to access memory after it's been freed. The results are undefined and it's entirely possible that your program will crash as a result of it.