gpt4 book ai didi

c - 在链表末尾插入节点

转载 作者:太空宇宙 更新时间:2023-11-04 10:13:12 25 4
gpt4 key购买 nike

我在链表末尾插入节点时遇到问题。我和我问过的其他人的逻辑似乎很好,但问题仍然存在,我不知道它可能发生在哪里。我很好地插入了第一个节点,它打印正确。但是,当我尝试插入以下节点时,就好像另一个节点已被删除并被新节点取代。这是我正在使用的功能:

struct client_info{
pthread_t client_ID;
int sockfd;
struct chat chats;
char user[NAMELEN];
struct client_info *next;
char current[NAMELEN];
};

struct header{
struct client_info *fnode, *lnode;
}client_head;
void client_insert(struct client_info *node){
if(client_head.fnode == NULL){
client_head.fnode = node;
client_head.lnode = node;
}
else{
client_head.lnode->next = node;
client_head.lnode = node;
}
}
void display_clients(){
struct client_info *tmp = client_head.fnode;
while(tmp!=NULL){
printf("Username: %s\nSocket: %d\n--------------------\n",tmp->user,tmp->sockfd);
tmp = tmp->next;
}
}

//inside main.
while(1){
size = sizeof(struct sockaddr_in);
if((clientfd = accept(sockfd, (struct sockaddr *)&client_addr,(socklen_t*)&size))>0){
printf("Client accepted\n");
struct client_info clinfo;
clinfo.sockfd = clientfd;
clinfo.next = NULL;
pthread_mutex_lock(&mutex);
client_insert(&clinfo);
pthread_mutex_unlock(&mutex);
pthread_create(&clinfo.client_ID, NULL, client_commands_handler, (void *)&clinfo);
}
else{
perror("accept");
}
}
return 0;
}

main 中的接受函数,是因为我将其用于聊天程序。此代码中的 fnode 和 lnode 分别是指向列表的第一个和最后一个节点(头和尾)的指针。因此,例如,我有一个名为 jack 的连接客户端,其套接字号为 5,他是第一个也是唯一一个连接的客户端,它会正确地打印出 jack 和 5。但是,如果是第二个客户端,amy 使用套接字 3 加入,它只会打印出艾米和 3,没有第一个客户,依此类推。

最佳答案

在您的 while 循环中,您将 clinfo 声明为 struct client_info 的一个实例。然后将该变量的地址传递给 client_insert 以将该变量的地址放入列表中。

当您到达循环末尾时,该变量超出范围。所以现在你有了一个超出范围的变量的地址。随后使用该地址调用 undefined behaivor .

至于为什么事情似乎被覆盖了,这正是正在发生的事情。在每次循环迭代中,您都有一个 struct client_info 的实例,它恰好(由于未定义的行为)与上次循环具有相同的地址。因此,您每次都将相同的地址传递给 client_insert

您需要动态分配 struct client_info 的实例并将其添加到列表中。

  struct client_info *clinfo = malloc(sizeof(*clinfo);
if (!clinfo) {
perror("malloc failed");
exit(1);
}
clinfo->sockfd = clientfd;
clinfo->next = NULL;
pthread_mutex_lock(&mutex);
client_insert(clinfo);
pthread_mutex_unlock(&mutex);
pthread_create(&clinfo->client_ID, NULL, client_commands_handler, clinfo);

关于c - 在链表末尾插入节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47718361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com