简体   繁体   中英

How to delete node from linked list after I print the contents?

I have a program in c which receives messages from different clients and servers. When the messages come in it adds the message to that list. After the message is added to the list I print it on the screen and on the other servers. But i want to delete the node that contains the message after it is printed so when the the print function gets called only prints the new messages. How can I delete the node after print?

Here is my struct:

typedef struct trade_list {
    char* trader_msg;
    u_int32_t id_of_sender;
    int sender_timer;
    int local_time;

    struct trade_list *next;
}trade_list;

trade_list *head = NULL;

And here is how I print:

  void print_trades()
    {

        trade_list * newnode = head;
        trade_list *previous = NULL;

            while (newnode) {

             previous = newnode;

              if ((elapsed - newnode->local_time >= 8)) 

             printf ("%s\n", newnode->trader_msg);
             newnode = newnode->next;

                if (previous == NULL)
                    head = newnode->next;
                else
                    {
                    previous->next = newnode->next;

                    free(newnode);
                    }
                }
}

Thus gives me a segmentation fault. I tried changing the newnode->next to just newnode in the else part. previous->next = new node; It didn't give me an error but it did not erase the node as it kept printing that node every time the print function was called

Instead of having print_trades depend on the global variable head , make it receive this 'head' as an argument and print from there. It's much better design wise.

 void print_trades(trade_list* head){ ... }

Then if you are adding the new nodes to the end of the list, you can print it starting from the first new one. If you are not using this information other than to print them, then there is no need to store them in a global list. Just use a local list within the function that receives them, and print that list.

Deleting a list is usually done by calling free(ptr) on each of the pointers. Since you know how to add nodes to the list, you will know how to inverse that appropiately.

At the start of your function:

trade_list *prev = NULL;

At each iteration in your loop, before newnode = newnode->next; add prev = newnode .

Then to delete:

if (prev == NULL) /* replace the head */
   head = newnode->next;
else
   prev->next = newnode->next;

/* free newnode? */

Fairly simple.

EDIT : You should really have some functions like list_create , list_add , list_remove associated with your data structure, rather than just chucking like the remove code into a print function. That's the first thing I do when I create any sort of data structure.

Another option is to have your linked list like:

typedef struct trade_node {
   char* trader_msg;
   u_int32_t id_of_sender;
   int sender_timer;
   int local_time;

   struct trade_node *next;
} trade_node;

typedef struct trade_list {
   trade_node *head;
   /* trade_node *foot; ? */
   size_t length;
} trade_list;

EDIT2 : As for your edit, change print_trades to something like:

void print_trades()
{
   trade_list *prev = NULL, *next;
   trade_list *newnode = head;

   while (newnode) {

      if ((elapsed - newnode->local_time >= 8)) {    
         printf ("%s\n", newnode->trader_msg);

         /* temp variable for newnode->next */
         next = newnode->next;

         if (prev == NULL) /* replace the head */
            head = next;
         else
            prev->next = next;

         /* free newnode->trader_msg? */
         free(newnode);

         /* don't update prev */
         newnode = next;
      }
      else {
         prev = newnode;
         newnode = newnode->next;
      }

   }
}

In your code, previous will never be NULL since you set it to newnode at the start of the loop, and newnode also shouldn't equal newnode->next until after newnode has been processed completely. You're also using newnode after you've free d it.

Take some time to review Linked List handling and deletion of items from linked lists... once your "print" executes just do a delete...

Basically you want to have some trade_list Pointer objects that point to the node to-be deleted and the previous node. Have the previous node's "next" point to the node-to-be-deleted's next and then free the memory on the deleted node...

Start...
NODE1->NODE2->NODE3
  ^      ^
  |      |
*temp1 *temp2

temp1 = NODE1;
temp2 = NODE2;  //or temp2 = temp1->next;

Next...
  +-------------+
  |             V
NODE1  NODE2->NODE3
  ^      ^
  |      |
*temp1 *temp2

temp1->next = temp2->next;
free(temp2);

After...
NODE1-------->NODE3

//temp1 still = NODE1
//temp2 = null

Have the pointer objects iterate through the list with your while loop as you go so you don't end up out of sync. Also be sure to check for null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM