Дело 1:
struct node *root = (struct node *) malloc(sizeof(struct node));
assert(root->left == NULL); /* not failed. Why? */
assert(root->right == NULL); /* not failed. Why? */
Это случайность и, как правило, не удастся. Нет никакой гарантии, что ошибочная память из кучи будет обнулена - для этого вам нужно calloc
. Тем не менее, многие отладочные библиотеки времени выполнения, которые я видел, обнуляют выделенную память, поэтому я могу поверить, что это работает для вас в режиме отладки. Это может варьироваться между режимами отладки и выпуска.
Случай 2:
static struct node root2;
Глобальные переменные обнуляются по умолчанию. Я думаю, что это гарантированное поведение, так что это правильно.
Дело 3:
struct node root1;
assert(root1.left == NULL); /* this failed. Why? */
assert(root1.right == NULL); /* this failed. Why? */
Это размещается в стеке и остается неинициализированным. Опять же, нет никаких гарантий относительно значений, которые вы оставили здесь, так что вы ожидаете, что это не получится.