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

C语言Trie树add函数内存泄漏与段错误问题排查求助

修复Trie字典的段错误问题

我帮你找到了导致段错误的核心问题,主要出在newdict函数的内存分配逻辑上,另外addword也需要补充初始检查,下面一步步拆解:

1. newdict函数的致命错误

你的newdict完全搞错了内存分配的对象和大小:

  • 首先,Dict是struct __tnode__*的typedef,所以sizeof(Dict)是指针的大小(通常8字节),而我们需要分配的是整个TNode结构体的大小,应该用sizeof(TNode)
  • 其次,函数参数dp是Dict*(也就是struct __tnode__**),我们要给*dp(指向TNode的指针)分配内存,而不是给dp本身分配
  • 你一开始把*dp = NULL,然后立刻给dp赋值,这会让原来传入的指针地址丢失,完全没起到初始化字典的作用

修复后的newdict应该是这样:

void newdict (Dict *dp) {
    // 先给*dp分配结构体大小的内存
    *dp = (Dict)malloc(sizeof(TNode));
    if (*dp == NULL) {
        barf("Failed to allocate memory for new node");
        return;
    }
    // 初始化结束标记和所有子节点为NULL
    (*dp)->eow = FALSE;
    for (int i = 0; i < VECSIZE; i++) {
        (*dp)->cvec[i] = NULL;
    }
}

2. addword的初始检查缺失

当你调用newdict初始化字典后,如果内存分配失败(或者原来的newdict没正确初始化),传入addword的r会是NULL,这时候直接访问pCrawl->cvec[index]就会触发段错误。所以要先加一个检查,同时还要防范非法字符导致的数组越界:

void addword (const Dict r, const word w) {
    if (r == NULL || w == NULL) {
        barf("Invalid input to addword");
        return;
    }
    int level;
    int length = strlen(w);
    int index;
    Dict pCrawl = r;
    for (level = 0; level < length; level++) {
        index = CHAR_TO_INDEX(w[level]);
        // 确保字符是合法的小写字母,避免数组越界
        if (index < 0 || index >= VECSIZE) {
            barf("Invalid character in word");
            return;
        }
        if (!pCrawl->cvec[index]) {
            newdict(&(pCrawl->cvec[index]));
        }
        pCrawl = pCrawl->cvec[index];
    }
    pCrawl->eow = TRUE;
}

3. 额外的新手注意事项

  • 注意Dict是指针类型的typedef,这种写法容易混淆,以后写代码时可以尽量避免直接typedef指针,除非有明确理由
  • 内存分配后一定要检查是否成功,避免后续访问NULL指针
  • CHAR_TO_INDEX宏要确保输入的字符是小写字母,否则会得到非法的index,导致数组越界(比如输入大写字母、数字或符号)

修复后,你的Trie结构应该能正常工作了,编译运行后段错误应该会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:04:15