You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CS50 Lab血型遗传实验触发segmentation fault错误排查

CS50血型遗传模拟程序段错误修复

问题现象

  • 程序运行触发segmentation fault(段错误),报错指向代码第56行
  • Valgrind内存检测提示存在8字节未初始化值被访问,该未初始化值由create_family函数内的malloc堆分配产生

错误根因

代码一共存在3处逻辑错误,直接触发崩溃和内存问题:

  1. 递归创建父代节点后,未将父代指针赋值给当前节点的parents数组成员。malloc分配的内存不会自动初始化成员值,p->parents[0]、p->parents[1]是存储随机垃圾值的野指针,直接解引用访问就会触发未初始化内存访问、野指针崩溃,这也是Valgrind报错的核心原因。
  2. create_family函数末尾错误返回NULL,没有返回新创建的节点指针,导致main函数拿到的根节点指针为空,后续打印、释放内存的操作全部异常。
  3. free_family函数的递归释放逻辑有缺陷:仅判断p->parents[0]非空时才递归释放两个父节点,会出现父节点内存漏释放的问题。

修复代码

1. 补全父代指针赋值逻辑

在create_family的generations > 1分支中,递归生成父代节点后,先把父代指针存入当前节点的parents成员,再读取等位基因:

if (generations > 1)
{
    person *person0 = create_family(generations - 1);
    person *person1 = create_family(generations - 1);
    // 补全:将父代指针绑定到当前节点
    p->parents[0] = person0;
    p->parents[1] = person1;
    // 随机继承父母的等位基因
    p->alleles[0] = p->parents[0]->alleles[rand() % 2];
    p->alleles[1] = p->parents[1]->alleles[rand() % 2];
}

2. 修正create_family返回值

将函数末尾的返回语句从return NULL;改为返回实际创建的节点:

// 返回新创建的人员节点
return p;

3. 修复free_family递归逻辑

去掉多余的父节点非空判断,直接递归释放两个父节点即可,函数入口的base case已经处理了空指针场景:

void free_family(person *p)
{
    if (p == NULL)
    {
        return;
    }
    // 直接递归释放双亲,无需提前判空
    free_family(p->parents[0]);
    free_family(p->parents[1]);
    // 释放当前节点
    free(p);
}

报错对应说明

Valgrind提示的8字节未初始化值,对应64位系统下指针类型的长度,正好对应未赋值的p->parents数组成员。报错指向的代码行就是首次解引用未初始化父指针的位置,野指针指向非法内存地址,直接触发段错误。


内容的提问来源于stack exchange,提问作者jdog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:48:28