2010-12-08 1 views
1

Die obige Funktion wird an Pthreads übergeben. Wenn das Programm ausgeführt wird, erhalte ich einen Segmentierungsfehler. Sobald ich den Anruf zu free(sub) mein Code funktioniert gut kommentieren. Ich kann nicht herausfinden, warum? Können wir Speicher in Threads dynamisch freigeben? Da der Heap unter allen Peer-Threads geteilt wird, die dem Haupt-Thread zugeordnet sind.Freigeben eines Heap zugeordneten Bereichs mit einer Funktion, die von pthred ausgeführt wird, löst Segmentierungsfehler

bearbeiten 1- vollständige Code

void *do_chld(void *arg) 
{ 

    int  new_fd = (int) arg; 
    int  i,n,val; 
    char buf[255]; 
    char *sub; 


    sub = malloc(255 * sizeof(char)); 

    printf("Child thread [%d]: Socket number = %d\n", pthread_self(), new_fd); 

    /* read from the given socket */ 
    n = read(new_fd,buf,100); 
    if(n<0){ 
      fprintf(stderr,"Receieving Failed\n"); 
      exit(2); 
    } 
    //process 
    printf("Received %s \n",buf); 

    val = checkSpelling(buf) ; 
    if(val){ 
     sub = "Correct Spelling"; 
    } 
    else{ 
     sub = "InCorrect Spelling"; 

    } 
    n = 0 ; 

    n = write(new_fd,sub,strlen(sub)); 
    if(n<0){ 
     fprintf(stderr,"Sending Failed\n"); 
     exit(2); 
    } 


    /* close the socket and exit this thread*/ 
    close(new_fd); 
     free(sub); 
    pthread_exit((void *)0); 
} 

Antwort

3

Sie weisen dem Zeiger sub ein Zeichenfolgenliteral zu - die Zeichen "Korrekte Rechtschreibung"/"Increct Rechtschreibung" - und versuchen dann, es mit free() freizugeben. String-Literale werden im Code statisch zugewiesen und können nicht freigegeben werden.

Im Wesentlichen der Zeiger sub zum Zeitpunkt der free() Aufruf zeigt auf etwas, das nicht mit malloc() zugeordnet wurde.

denke ich, das Hauptproblem ist jedoch, dass Sie eine Zeigerzuweisung durchführen, wenn Sie wahrscheinlich eine Zeichenfolge kopieren wollen, so dass der Inhalt der Zeichenfolge in der Gegend sind Sie von malloc() bekam.

EDIT:

Sie möchten an den strcpy() und strdup() Funktionen einen Blick haben. strcpy() würde in Ihrem Fall in Ordnung sein, obwohl es besser wäre, wenn Sie strncpy() stattdessen verwendet wurden.

strdup() ist in etwa eine Kombination aus strlen() + malloc() + strcpy() und ist usally die einfachste Option, wenn Sie eine Kopie einer Zeichenkette in den Heap-Speicherbereiche haben wollen, so dass sie später mit free() befreit werden können.

EDIT 2:

In Ihrem Code über Sie verwenden, um die sub Puffer nur für die Antwortnachricht, und sie dann freizugeben. Wenn dies das endgültige Verhalten Ihres Codes ist, können Sie einfach die malloc() und free() Anrufe entfernen und es wäre wahrscheinlich in Ordnung.

2

Das klingt wie Heapbeschädigung mir - haben Sie Ihr Programm versucht, läuft ohne /* -- Some Code -- */?

Obwohl der Code, den Sie gezeigt haben, sieht gut aus, ist es möglich, dass der Code nicht möglicherweise überschrieben (beschädigt) Teile außerhalb des zugewiesenen Speicher aus dem Heap gezeigt haben. Obwohl dies nicht einen Fehler an dem Punkt verursacht haben kann, wo der Speicher beschädigt ist und nicht zu einem Fehler führen, wenn der Prozess beendet wird, könnte man sehr leicht die Datenstruktur geändert hat, die die zugewiesenen Speicher in eine Weise beschrieben, die den Anruf veranlasst, free zum scheitern verurteilt.

Update: an Ihrem zweiten Code sucht Entsendung es in der Tat könnte sein, dass Sie versehentlich den Wert der sub Zeiger (auch bekannt als Stapelbeschädigung) modifizieren - möglicherweise durch über das Ende der buf zu schreiben. Dies würde mit ziemlicher Sicherheit dazu führen, free zum Scheitern verurteilt.

Überprüfen Sie den Wert von sub kurz nach dem malloc Anruf, und einmal dann wieder kurz vor dem free sicherzustellen, dass es nicht geändert hat.

Update 2: Scratch dass - Thkala Hat die richtige Antwort.

+0

Ich bin sicher, dass ich nicht auf den Haufen innerhalb der/* --- Einige Code - */zugreifen. Ich poste das gleiche als Referenz. –

+0

@Eternal - Es könnte stattdessen sein, dass der Wert von "sub" geändert wird - siehe meinen aktualisierten Beitrag für weitere Details. – Justin

0

Weil 'sub' die Referenz verloren hat, die die Adresse des Ergebnisses von malloc() ist. Zuerst zeigte 'sub' die Anfangsadresse des Ergebnisses von malloc() an. Wenn Sie jedoch "sub" "Rechtschreibfehler korrigieren" lassen, zeigt "sub" nicht den malloc() - ed-Speicher an. Es wurde die Anfangsadresse dieses Strings - "Corr--" -. Wenn Sie 'sub' verwenden, um zu versuchen, den malloc() - ed Speicher freizugeben, würde der Compiler Ihnen einen Fehler senden, weil 'sub' nicht auf die malloc() - Adresse zeigt und Sie die Zeichenfolge nicht löschen können (char arrary) .

Sie nicht verpassen, dass die Unter ist einer der Zeiger Wert, nicht der Speicher selbst.