CS50 Pset5 Speller程序内存错误求助:非法访问8字节内存
CS50 Pset5 Speller 内存错误修复
问题概况
完成CS50问题集5的Speller程序后,所有功能正常运行,但Valgrind检测出内存错误:unload函数中ptr = tmp->next(dictionary.c第104行)存在非法内存访问,错误总数143091个,虽无内存泄漏但存在大量无效内存读取。
错误原因
当前unload函数的内存释放逻辑存在顺序错误:
while (ptr != NULL) { tmp = ptr; free(ptr); ptr = tmp->next; }
tmp与ptr指向同一块内存,调用free(ptr)后该内存已被操作系统回收,此时再通过tmp->next访问已释放的内存,属于无效内存读取,触发Valgrind错误提示。
修复方案
调整内存释放顺序,先保存下一个节点的地址,再释放当前节点:
// Unloads dictionary from memory, returning true if successful, else false bool unload(void) { node *current = NULL, *next_node = NULL; for (int i = 0; i < N; i++) { current = table[i]; while (current != NULL) { // 先保存下一个节点的地址,避免释放后丢失 next_node = current->next; // 释放当前节点 free(current); // 移动到预先保存的下一个节点 current = next_node; } // 将桶指针置空,避免悬空指针 table[i] = NULL; } return true; }
修改说明
- 提前用
next_node保存下一个节点的地址,确保当前节点释放后仍能正常遍历链表。 - 释放当前节点后,直接使用预存的
next_node更新循环变量,彻底避免访问已释放内存。 - 添加
table[i] = NULL,将每个哈希桶的指针置空,防止后续误操作访问悬空指针。
验证
修改后重新用Valgrind检测,ERROR SUMMARY会显示为0个错误,内存释放逻辑完全合法。
内容的提问来源于stack exchange,提问作者Aryan Raj
相关产品推荐
相关产品推荐

