c - 卸载功能的另一个问题,节点设置为 null 正在以某种方式重新填充
问题描述
我正在制作一个从内存中释放哈希表的函数。目前,我只是试图将节点设置为 NULL 以确保它正确迭代。但是我得到了我不明白的输出。
这是我当前的哈希表:
这是我目前的输出。这是一个无限循环:
这是我的代码:
bool unload(void)
{
// For all elements in the hash table
for (int i = 0; i < N; i++)
{
// Until break...
while (1)
{
// Set traversal node at hash index i, set trailing traversal node to NOLL
node *curr = table[i];
printf("start CURR WORD: %s (%p)\n", curr->word, curr); // DEBUG
node *prev = NULL;
// If current is NULL, meaning the index head is null, break
if (curr == NULL)
{
printf("CURR is NULL: BREAKING...\n"); // DEBUG
break;
}
// if the index head is not NULL, but its' next pointer is NULL, set current to NULL, next iteration
if (curr->next == NULL)
{
printf("HEAD (%s)->Next: NULL, SETTING HEAD TO NULL...\n", curr->word); // DEBUG
curr = NULL;
continue;
}
// While current is not null, set trailing traversal node to current, set current to its next pointer
while (curr != NULL)
{
printf("CURR is not NULL: (%s), NEXT...\n", curr->word); // DEBUG
prev = curr;
curr = curr->next;
}
// when current is NUll, set trailing traversal node to NULL
printf("CURR IS NULL, SETTING PREVIOUS (%s) TO NULL...\n", prev->word);
prev = NULL;
printf("PREV WORD: %s\n", prev->word);
}
}
return true;
}
第一个if
条件,if (curr == NULL)
,似乎触发得很好。table[0]
是NULL
,所以它打破了 的第一次迭代while (1)
。其余的在做什么,我不明白。正如预期的那样,它将跳过前两个节点,登陆NULL
. 然后,显然,它将前一个节点设置为NULL
,就像它应该的那样。但是在 的下一次迭代中while (1)
,它应该设置为的节点NULL
仍然被填充,尽管 command ,并且尽管在该命令(和)触发prev = NULL;
之前和之后的两个打印语句也是如此。printf("CURR IS NULL, SETTING PREVIOUS (%s) TO NULL...\n", prev->word);
printf("PREV WORD: %s\n", prev->word);
有人可以告诉我这里出了什么问题吗?为什么设置为 NULL 的节点会在下一次迭代中重新填充?提前致谢。
编辑:这是我想要实现的目标......
LIST 00: { } LIST 01: {NODE 1, NODE 2, }
UNTIL THE HEAD IS NULL
IF the head is NULL
BREAK
IF the head is not NULL, but its NEXT pointer is NULL
Set head to NULL
next iteration
IF neither the head nor its next pointer are NULL
Move to the next node until you reach NULL
IF the current node is NULL
Set the previous node to NULL
在 List 00 中,第一个IF
遇到了,然后就中断了。在列表 01 中,遇到第三个IF
,它移动到NULL
。然后遇到第四个IF
,它之前的节点应该设置为NULL
. 在迭代 2 开始时,它应该如下所示:
LIST 00: { } LIST 01: {NODE 1, }
在这种情况下,满足第二个IF
。它应该将 head 设置为NULL
,然后继续下一次迭代:
LIST 00: { } LIST 01: { }
现在,第一个IF
满足了,所以它应该打破while (1)
循环并继续循环中的下一个迭代for
。
解决方案
无限循环是由while(1)
循环引起的。在顶部,curr
设置为table[i]
。在循环中,curr 设置为 null,但这并不重要,因为break
语句永远不会被命中,并且 curr 在循环顶部被重置为相同的值。
我评论了代码以帮助解释流程:
bool unload(void)
{
// For all elements in the hash table
for (int i = 0; i < N; i++)
{
// Until break...
while (1)
{
// Set traversal node at hash index i, set trailing traversal node to NOLL
node *curr = table[i]; // <<<<<<< curr set to same value, curr in NOT null, and i is the same as last loop
printf("start CURR WORD: %s (%p)\n", curr->word, curr); // DEBUG
node *prev = NULL;
// If current is NULL, meaning the index head is null, break
if (curr == NULL) // <<<<<<<<<<<< skip this, curr is NOT null
{
printf("CURR is NULL: BREAKING...\n"); // DEBUG
break; // <<<< never gets here
}
// if the index head is not NULL, but its' next pointer is NULL, set current to NULL, next iteration
if (curr->next == NULL) // <<<<<<<<< skip this, next is NOT null
{
printf("HEAD (%s)->Next: NULL, SETTING HEAD TO NULL...\n", curr->word); // DEBUG
curr = NULL;
continue;
}
// While current is not null, set trailing traversal node to current, set current to its next pointer
while (curr != NULL) // <<<<<<<<<< move curr forward until curr = null
{
printf("CURR is not NULL: (%s), NEXT...\n", curr->word); // DEBUG
prev = curr;
curr = curr->next;
}
// <<<<<<<<<<<<<<<<<<< at this point, curr = null
// when current is NUll, set trailing traversal node to NULL
printf("CURR IS NULL, SETTING PREVIOUS (%s) TO NULL...\n", prev->word); // <<<< no curr change
prev = NULL; // <<<< no curr change
printf("PREV WORD: %s\n", prev->word); // <<<< no curr change
}
}
return true;
}
- - - - 更新 - - - -
根据更新后的帖子,此代码应获得正确的结果:
bool unload(void)
{
// For all elements in the hash table
for (int i = 0; i < N; i++)
{
node *curr = table[i]; // set head
if (curr == NULL) continue; // skip, go to next head
curr = curr->next; // top of linked list
// set linked list elements to null
while (curr != NULL)
{
printf("CURR is not NULL: (%s), NEXT...\n", curr->word);
node *prev = curr;
curr = curr->next
printf("SETTING PREVIOUS (%s) TO NULL...\n", prev->word);
prev = NULL;
printf("PREV WORD: %s\n", prev->word);
} // while curr
} // for i
}
推荐阅读
- node.js - 尝试打开应用程序时 Heroku 错误代码 H13
- flutter - authStateChanges 仅在调试模式下有效
- python - 使用 libimobiledevice python 绑定的正确方法是什么?
- python - 具有固定主机名的 Kubernetes
- asp.net-core - 使用 UseSerilogRequestLogging 时,Serilog 时间戳在请求结束时,我可以覆盖它吗?
- c# - 错误 CS0411 ASP.NET Core Web 应用程序
- apache - 基于规则和错误类型 htaccess 的重定向
- sql - SQL Server Management Studio 会同步运行多个语句吗?
- asp.net-core - $.getJSON 给出未定义的结果(Razor 网页和 JSONresult)
- git - git config --global credential.helper 'cache' 的 git 凭证缓存有多安全?