This function will take a particular node of linked list and make it Last node.
void lastNode(struct list *node)
{
struct list* temp = node->next;
node->next = NULL;
struct list* temp2;
while(temp)
{
temp2 = temp->next;
printf("%p \n",temp);
free(temp);
temp = temp2;
}
}
int main()
{
struct list d={4,NULL};
struct list c={3,&d};
struct list b={2,&c};
struct list a={1,&b};
struct list *node = &a;
开发者_如何学编程 lastNode(&b);
while(node)
{
printf("%d \n",node->d);
node=node->next;
}
return 0;
}
but it is giving me error in freeing a node.
Looking at your full code:
struct list c={3,&d};
struct list b={2,&c};
lastNode(&b);
It is not legal to free
temp
since it wasn't allocated using malloc
.
struct list* temp = node->next; /* temp is now &c. You can't free it. */
while(temp)
{
/* ... */
free(temp); /* Tries to free &c which is on the stack. */
}
Update: This was written before the caller of the free function was provided. Now that I see this I would say that yeah, you can't call free
on a stack address. However my original answer is preserved below, about how to better do a list removal...
I don't see a free
bug pop out at me suddenly, but.... it seems like this approach will only work if the node
passed in is the first node. If it's some node other than the first you will need a pointer to the previous one so you can set prev->next = node->next
.
Actually, thinking about this more... If all you're doing is taking a node and making it the last one, why do you need to free
anything? It seems like this code frees the entire list starting from temp
. If that is your intention I recommend something more like this:
void free_all_at_node(struct list **list, struct list *node_to_free)
{
struct list *n = *list, *prev = NULL;
// Search for node_to_free, updating prev to indicate the last node we saw.
//
while (n && n != node_to_free)
{
prev = n;
n = n->next;
}
// Check to see if we found it...
//
if (n == node_to_free)
{
// Do we have a previous node?
//
if (prev)
{
// Yes, update next pointer...
//
prev->next = NULL;
}
else
{
// This is the start of the list. Update the head...
//
*list = NULL;
}
// Now free stuff...
//
while (n)
{
struct list *next = n->next;
free(n);
n = next;
}
}
}
That assumes you want node_to_free
to be the first node to free, and hence we search for it given the start of the list. Another alternative is to have the caller specify the node before the first node to free. (It looks like your code is actually trying to do this...) I might prefer to do it like this:
void free_after_node(struct list *n)
{
// If the node is NULL or has no next node, there is nothing to do.
//
if (n && n->next)
{
// Start at the node after the first, since we want to keep the first
// one around.
//
n = n->next;
// Now free...
//
while (n)
{
struct list *next = n->next;
free(n);
n = next;
}
}
}
精彩评论