这是 cs50pset 5 的一部分,所以它是一个剧透。函数假设从链表数组中卸载附加的字符串,某种哈希表(我不知道它是否正确定义(。但它似乎造成了一个赛格错误。你能说这个函数是否会导致seg错误,或者我应该检查问题的其他功能吗?非常感谢您的时间。
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table
const unsigned int N = 1000; // trying to find most optimized N it could be different
// Hash table
node *table[N];
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
node* iterf; //forward iteration
node* iterb; //pointer that stays behind of iterf
iterf = table[i];
iterb = iterf;
while (iterb != NULL)
{
iterb = table[i];
iterf = iterb -> next;
free(iterb);
iterb = iterf;
}
}
return true;
}
考虑这个循环
node* iterf;
node* iterb;
// ...
iterf = table[i];
iterb = iterf;
while (1)
{
if (iterf == NULL)
{
free(iterf); // <-- Why are you freeing a NULL pointer?
}
iterf = iterf -> next; // <-- iterf CAN be NULL!
free(iterb);
iterb = iterf;
} // How can this be stopped? When it segfaults?
目前还不清楚为什么外部循环应该在第一个 NULL 指针处停止,返回 false,但内部循环应该只是一个正常的单向链表释放。
node *current = table[i];
while ( current != NULL )
{
// Now I know that the pointer can be dereferenced
node *next = current->next;
// Free it only after saving the next
free(current);
current = next;
}
我在删除//THIS LINE 双重迭代消失的那一刻找到了解决方案。因为由于该行指针回到开头并尝试释放已经释放的内存。至少我是这么想出来的。如果有任何意见或补充,请写下来。感谢所有的帮助,很幸运有这样一个有用的社区:)
iterf = table[i];
iterb = iterf;
while (iterb != NULL)
{
iterb = table[i]; // THIS LINE
iterf = iterb -> next;
free(iterb);
iterb = iterf;
}