2017-12-08 3 views
0

Ich habe Probleme beim Einfügen eines Knotens am Ende einer verknüpften Liste. Die Logik für mich und andere, die ich gefragt habe, scheint in Ordnung zu sein, aber das Problem bleibt und ich habe keine Ahnung, wo es passieren könnte. Ich füge den ersten Knoten in Ordnung, es druckt korrekt. Wenn aber ich versuche, den folgenden Knoten einzufügen, dann ist es, als ob die anderen Funktionen sind durch die neuen one.Here gelöscht und ersetzt wurde ich verwende:Einfügen von Knoten am Ende einer verknüpften Liste

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

die funtion in Haupt annimmt, wird weil ich das für ein Chat-Programm verwende. fnode und lnode in diesem Code sind jeweils die Zeiger auf den ersten und letzten Knoten der Liste (head und tail). So zum Beispiel habe ich einen verbundenen Client namens Jack mit Socket Nummer 5, er ist der erste und einzige angeschlossene Client, würde es richtig auszugeben Jack und 5. aber wenn ein Second-Client, Amy mit Socket 3 verbindet würde es nur drucken aus Amy und 3, ohne den ersten Kunden, und so weiter und so fort.

+2

Was ist 'lnode'? Was ist 'Fnode'? Entfernen Sie den irrelevanten Code wie Threading und Unit-Test Ihre Listenimplementierung. Stellen Sie auch ein korrekt formatiertes [mcve] bereit. –

+0

Haben Sie einen Debugger? Sie können prüfen, ob der Zeiger auf den Kopf der Liste für jeden Thread gleich ist. Ich liefere, dass Sie besonders vorsichtig sein müssen, um sichere Listen zu erstellen. –

Antwort

1

Innerhalb Ihrer while Schleife erklären Sie clinfo als eine Instanz von struct client_info. Dann übergeben Sie die Adresse dieser Variablen an client_insert, um die Adresse dieser Variablen in die Liste aufzunehmen.

Wenn Sie das Ende der Schleife erreichen, wird diese Variable nicht mehr verwendet. Jetzt haben Sie die Adresse einer Variablen außerhalb des Gültigkeitsbereichs. Anschließend wird unter Verwendung dieser Adresse undefined behaivor aufgerufen.

Warum Dinge scheinen überschrieben zu werden, das ist genau das, was passiert. Bei jeder Schleifen-Iteration haben Sie eine Instanz von struct client_info, die (aufgrund eines nicht definierten Verhaltens) zufällig die gleiche Adresse wie die letzte Schleife hat. Sie geben also jedes Mal dieselbe Adresse an client_insert weiter.

Stattdessen müssen Sie eine Instanz von struct client_info dynamisch zuweisen und diese der Liste hinzufügen.

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

genau was passierte! vielen Dank. – jonelearn

Verwandte Themen