全局结构体指针递归调用后未更新、子节点无法访问问题求助
问题解答
问题1:第一段代码中全局root无法访问子节点的原因
核心问题是**generate函数错误地使用全局变量root存储当前创建的节点**,递归调用时会反复覆盖这个全局变量,导致原本要构建的Trie树结构完全混乱:
- 每次调用
generate都会给全局root赋值新的malloc地址,递归深入时,全局root会被底层节点覆盖。 - 当递归返回上层时,上层函数中的
root已经不是之前创建的父节点,而是底层节点,导致父节点的character数组只有第一个元素被正确赋值,其余元素都是未初始化的垃圾值(大概率是NULL)。 - 最终
main中拿到的根节点,其大部分子节点都是NULL,所以在free_hashtable中打印any->character[0]会显示nil;而全局root最后指向的是最底层的节点,该节点的character数组被显式设为NULL,所以root->character[0]也是nil。
修正方案:
去掉全局root,改用局部变量存储当前创建的节点:
trie *generate(int times) { // 用局部变量代替全局root trie *current = malloc(sizeof(trie)); if (current == NULL) { // 增加内存分配失败检查 return NULL; } current->next = NULL; if (times > 0) { for (int i = 0; i < nodes; i++) { current->character[i] = generate(times - 1); } } else { for (int i = 0; i < nodes; i++) { current->character[i] = NULL; } current->next = malloc(sizeof(hash_table)); if (current->next != NULL) { // 增加内存分配失败检查 current->next->next = NULL; } } return current; }
同时删除全局trie *root;,main中改为局部变量:
int main(void) { trie *root = generate(height); // ... 其余代码不变 }
问题2:第二段代码中递归调用地址未切换的原因
同样是**错误使用全局变量root**导致的结构破坏:
- 每次调用
generate都会覆盖全局root,递归到最底层(times=0)时,全局root指向最后创建的节点。 - 当递归返回上层时,上层函数中的
root已经被底层节点覆盖,此时执行root->next = generate(times-1),相当于给底层节点的next赋值为自身,形成了自环链表。 - 最终
main中拿到的root是底层节点,其next指向自己,所以free_dummy递归调用时永远传入同一个节点地址,打印的地址始终相同,还会触发无限递归直到栈溢出。
修正方案:
同样去掉全局root,改用局部变量:
test *generate(int times) { test *current = malloc(sizeof(test)); if (current == NULL) { return NULL; } strcpy(current->word, "dummy"); if (times != 0) { current->next = generate(times - 1); } else { current->next = NULL; } return current; }
删除全局test *root;,main中改为局部变量:
int main(void) { test *root = generate(3); // ... 其余代码不变 }
此外,free_dummy函数中存在逻辑错误:递归调用后立即free(any->next),会导致后续访问已释放的内存,修正后的free_dummy应该先递归再释放当前节点:
void free_dummy(test *any) { printf("%p\n", any); if (any->next != NULL) { free_dummy(any->next); } free(any); // 先递归释放子节点,再释放当前节点 }
内容的提问来源于stack exchange,提问作者DumbDumbie
相关产品推荐
相关产品推荐

