CS50 Lab5 inheritance血型模拟代码segmentation fault排查求助
CS50 Lab5 遗传血型模拟程序段错误修复
问题定位
代码触发段错误的核心原因是free_family函数的递归逻辑错误:
- 递归释放完当前节点的两个父节点后,代码错误地再次调用
free_family(p)而非直接释放当前节点内存。由于此时传入的p不为NULL,函数会无限重复进入自身逻辑,反复访问已经被释放的父节点野指针,最终栈溢出、访问非法内存触发段错误。 - 额外隐患:动态分配
person结构体内存时,没有检查malloc返回值,若内存分配失败返回NULL,后续访问结构体成员会直接触发空指针错误。
修复步骤
- 修正
free_family函数的释放逻辑,将错误的递归自调用替换为标准内存释放操作,修正后的完整函数如下:
// Free `p` and all ancestors of `p`. void free_family(person *p) { // 递归终止条件:节点为空直接返回 if (p == NULL) { return; } // 递归释放双亲节点 free_family(p->parents[0]); free_family(p->parents[1]); // 释放当前节点 free(p); }
- (可选加固)在
create_family函数的内存分配逻辑后增加空值检查,避免分配失败引发空指针访问:
// Allocate memory for new person person *newperson = malloc(sizeof(person)); if (newperson == NULL) { return NULL; }
同类错误规避方法
- 编写递归函数时,必须确认所有分支都能触达终止条件:处理树、链表等链式结构的递归操作时,处理完子节点后对当前节点的操作禁止再次递归调用自身,否则极易触发无限递归。
- 所有动态内存分配操作后,必须检查返回值是否为
NULL,从源头避免空指针访问。 - 段错误排查优先覆盖两类高频场景:一是空指针、野指针(已释放内存的指针)的成员访问,二是无限递归导致的栈溢出;使用调试工具查看函数调用栈,如果发现同一个函数被重复嵌套调用成百上千次,即可判定为递归逻辑错误。
运行错误截图

内容的提问来源于stack exchange,提问作者Okonjo Mitchel
相关产品推荐
相关产品推荐

