Stack Overflow Asked by Pleasant Nightmares on September 9, 2020
I’m making a function to free a hash table from memory. At the moment, I’m only attempting to set the nodes to NULL to make sure that it’s iterating correctly. But I’m getting output that I don’t understand.
This is my current hash table:
This is my current output. It’s an infinite loop:
And this is my code:
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: %sn", prev->word);
}
}
return true;
}
The first if
condition, if (curr == NULL)
, seems to be triggering just fine. table[0]
is NULL
, so it breaks the first iteration of while (1)
. What the rest is doing, I don’t understand. As intended, it will skip the first two nodes, landing on NULL
. Then, apparently, it will set the previous node to NULL
, like it’s supposed to. But in the next iteration of while (1)
, the node that it was supposed to have set to NULL
is still populated, despite the command prev = NULL;
, and despite the two print statements before and after that command (printf("CURR IS NULL, SETTING PREVIOUS (%s) TO NULL...n", prev->word);
and printf("PREV WORD: %sn", prev->word);
) triggering as well.
Can someone tell me what’s going wrong here? Why is the node that’s being set to NULL repopulating on the next iteration? Thanks in advance.
EDIT: Here is what I’m trying to achieve…
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
In List 00, the first IF
is met, and it breaks.
In List 01, the third IF
is met, and it moves until NULL
. Then the fourth IF
is met, and the node before it should be set to NULL
. At the beginning of iteration 2, it should look like this:
LIST 00: { } LIST 01: {NODE 1, }
In which case, the second IF
is met. It should set the head to NULL
, and move on to the next iteration:
LIST 00: { } LIST 01: { }
Now, the first IF
is met, so it should break the while (1)
loop and move on to the next iteration in the for
loop.
The infinite loop is caused by the while(1)
loop. At the top, curr
is set to table[i]
. In the loop, curr is set to null, but that does not matter because the break
statement is never hit and curr is reset to the same value at the top of the loop.
I commented the code to help explain the flow:
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: %sn", prev->word); // <<<< no curr change
}
}
return true;
}
------- UPDATE -------
Based on the updated post, this code should achieve the correct result:
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: %sn", prev->word);
} // while curr
} // for i
}
Answered by Mike67 on September 9, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP