从 C 中的双向 link 列表中删除特定项目

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

我用 C 语言编写了一个程序(服务器和客户端),其中服务器为连接到服务器的客户端提供聊天室服务。服务器允许您使用加密算法和协议交换数据。为了存储有关客户的信息,我创建了结构并将它们 link 编入双向 link 列表。现在我正在处理客户端与服务器断开连接的情况,我需要将其从列表中删除并将新列表正确地放回原处。

这是结构化的客户:

//客户端结构和新数据类型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; 

这是列表:

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

我添加了创建列表、释放列表、创建客户端、列出整个列表、在列表中查找特定客户端的功能,例如通过套接字、插入新客户端等...但我仍然无法编写从列表中删除特定用户并填充空白位置的函数。

我删除特定用户的函数如下所示:

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");
    }

}

当我调用函数时,应用程序崩溃了。

我的插入客户端函数:

//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++;

}

插入功能似乎正常,但删除功能逻辑有点模糊 我个人更愿意使用递归方法来处理链表 我没有完全测试这个片段,但我从很久以前写的旧代码中取出它并相应地改变它以匹配你的情况 我希望这会有所帮助

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);

}