Home > other >  Remove a specific item from the two-way link list in C
Remove a specific item from the two-way link list in C

Time:11-28

I created a program in C language (server and clients), where the server provides a chat room service to clients who connect to the server. The server allows you to exchange data with cryptographic algorithms and protocols. To store information about clients, I created structures and linked them in two-way link lists. Now I'm working on a case where a client disconnects from the server and I need to delete it from the list and put the new list back together properly.

This is strucute CLIENT:

//Client structure and new data type CLIENT

typedef struct client {
    char address_buffer[100];
    SOCKET sock_fd;
    salt_channel_t channel;
    socklen_t client_len;
    struct sockaddr_storage client_address;
    struct client *p_next;
    struct client *p_previous;
} CLIENT; 

And this is LIST:

    typedef struct {
    int count;
    CLIENT *p_head;
    CLIENT *p_tail;
} LIST; 

I added functions to create a list, release a list, create a client, list the whole list, find a specific client in the list, for example by socket, insert a new client etc ... but I still have trouble writing a function that removes a specific user from the list and fills in quite empty the place.

My function for deleting a specific user looks like this:

void realese_client(LIST *p_list,
                    CLIENT *p_client)
{
   CLIENT *p_new_previous;
   CLIENT *p_new_next;

    //p_list has only one p_client
    if ((p_list->p_head->sock_fd == p_client->sock_fd) && (p_list->p_tail->sock_fd == p_client->sock_fd))
    {
        free(p_list->p_head);
        free(p_list->p_tail);    
        p_list->p_head = NULL;
        p_list->p_tail = NULL;
    }
     //There are some p_client on the p_list but no p_head or p_tail
    else  if (p_list->p_tail != NULL)
    {   

        p_new_previous = p_client->p_previous;
        p_new_next = p_client->p_next;

        p_new_previous->p_next = p_new_next;
        p_new_next->p_previous = p_new_previous;
        free(p_client);

    } //p_list has p_client as p_tail
    else if (p_list->p_tail->sock_fd == p_client->sock_fd)
    {

        p_new_previous = p_list->p_tail->p_previous; 
        p_list->p_tail = p_new_previous;
        p_new_previous->p_previous = p_list->p_tail;

        free(p_client);

    }
    else 
    {   //p_list is empty

        printf("List is empty !!!\n");
        printf("Unable to delete p_client !!!\n");
    }

}

When I call function, the application crashes.

My function for insert client:

//Function for connecting a new node to the list
void  insert(LIST *p_list, 
            CLIENT *p_client)
{
      //There are some p_client on the p_list
    if (p_list->p_tail != NULL)
    {   
        //Connecting the last person as a new person
        p_list->p_tail->p_next = p_client; 
        //Joining a new person to a former last person
        p_client->p_previous = p_list->p_tail; 
        //Save a new p_tail
        p_list->p_tail = p_client; 
    }
    else 
    {   //p_list is empty

        //There is none in front of the p_client
        p_client->p_previous = NULL; 
        //Assigning a p_client to the list (head and tail)
        p_list->p_head = p_client; 
        p_list->p_tail = p_client; 
    }
    p_client->p_next = NULL;
    p_list->count  ;

}

CodePudding user response:

It seems that the insert function works properly but the delete function logic is kinda blurry personally I would prefer to use recursion approach to handle linked lists I didn't exactly test this snippet but I took it from old code I had written a long time ago and changed it accordingly to match your case i hope this will help

CLIENT * deleteNode(CLIENT * head, SOCKET socket_fd) {
  if(head == NULL) return NULL;
  if(head->socket_fd == socket_fd ){
    CLIENT *pre = head; 
    head=head->p_next;
    head->p_previous=NULL;
    free(pre);
    return head;
  }
  head->p_next=deleteNode(head->p_next,socket_fd);
  return head;
}

void realese_client(LIST *p_list,CLIENT *p_client){
   //check the validity of function arguments first for safety purposes
   if(p_list == NULL  || p_client == NULL) return;
   SOCKET socket_fd=p_client->socket_fd;
   ClIENT head=p_list->p_head;
   CLIENT tail=p_list->p_tail;
   //if list of the client is empty exit
   if(tail == NULL) return;


   //test if there is one node
   if(head == tail){
      if(head->socket_fd == socket_fd){
         p_list->p_head=NULL;
         p_list->p_tail=NULL;
         free(head);
      }
    return;
   }

   if(tail->socket_fd == socket_fd){
       p_list->p_tail=tail->previous;
       p_list->p_tail->p_next=NULL;
       free(tail);
       return;
   }   
   if(head->socket_fd == socket_fd){
       p_list->p_head=head->p_next;
       p_list->p_head->p_previous=NULL;
       free(head);
       return;
   }
  
 deleteNode(p_list->p_head,p_client->socket_fd);

}

  • Related