Why are these three methods different in C code?

I have some problems with this code. Pay attention to the comments. Why?

struct node { struct node *left; struct node *right; int value; }; static struct node root2; int main() { struct node *root = (struct node *) malloc(sizeof(struct node)); assert(root->left == NULL); /* not failed. Why? */ assert(root->right == NULL); /* not failed. Why? */ assert(root2.left == NULL); /* not failed. Why? */ assert(root2.right == NULL); /* not failed. Why? */ struct node root1; assert(root1.left == NULL); /* this failed. Why? */ assert(root1.right == NULL); /* this failed. Why? */ free(root); return 0; } 
+4
source share
3 answers

With root1, you declared a local instance of node and it will be on the stack. You do not initialize it, so it will contain garbage.

Using root2, you declared a global instance. The default startup code will clear the memory occupied by global groups.

Using root, it will exist on the heap and will contain garbage. This is just luck if the occupied memory contains 0 or not. If you use calloc instead of malloc, it will clear the memory for you.

+9
source

Case 1:

 struct node *root = (struct node *) malloc(sizeof(struct node)); assert(root->left == NULL); /* not failed. Why? */ assert(root->right == NULL); /* not failed. Why? */ 

This is an accident and usually fails. There is no guarantee that the malloced memory from the heap will be reset - you need a calloc for this. However, many of the debug time libraries I've seen will have zero allocated memory, so I can assume that this works for you in debug mode. This may vary between debug and release modes.

Case 2:

 static struct node root2; 

By default, global variables are nullified. I think this is guaranteed behavior, so that is correct.

Case 3:

 struct node root1; assert(root1.left == NULL); /* this failed. Why? */ assert(root1.right == NULL); /* this failed. Why? */ 

This is allocated on the stack and remains uninitialized. Again, there is no guarantee on what values ​​you will stay here, so you expect this to fail.

+4
source

When you highlight a new node, its sons are not NULLed by default. They get garbage values.
In addition, the assert macro is disabled if, at the time you turned on assert.h, a macro named NDEBUG was already defined. This allows the encoder to include many assert calls in the source code when debugging the program, and then disable all of them for the production version by simply including a line, for example:

 #define NDEBUG 

at the beginning of its code, before including assert.h.

For instance:

 #undef NDEBUG #include <assert.h> 
0
source

Source: https://habr.com/ru/post/1341624/


All Articles