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
相关产品推荐
相关产品推荐

