2010-12-08 34 views
1
void *do_chld(void *arg) 
{ 
    char *sub; 
    sub = malloc(255 * sizeof(char)); 

    /* 
     ------ Some Code ---- 
    */ 

    free(sub); 
    pthread_exit((void *)0); 
} 

上述函數傳遞給pthreads。當程序執行時,我得到了分段錯誤。一旦我評論對free(sub)的呼叫,我的代碼就可以正常工作。我無法弄清楚爲什麼?我們不能在線程中動態釋放內存嗎?由於堆在與主線程關聯的所有對等線程中共享。通過pthred throws分段錯誤釋放堆分配區域

編輯1-全碼

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

回答

3

您正在爲sub指針指定一個字符串文字 - 「正確拼寫」/「Incorect spelling」字符串,然後嘗試用free()釋放它。字符串文字在代碼中靜態分配,不能釋放。

本質上,指針在撥打free()時指向的是尚未使用malloc()分配的內容。

我認爲主要的問題,不過,是你進行指針賦值,當你可能想要做一個字符串複製,使字符串的內容是你從malloc()了該地區。

編輯:

你可能想看看在strcpy()strdup()功能。 strcpy()在你的情況下會很好,但如果你習慣了strncpy(),那會更好。

strdup()大致是strlen() + malloc() + strcpy()組合,是usally最簡單的選項,當你想擁有的堆內存區域的字符串的副本,以便它可以在以後用free()釋放。

編輯2:

在你上面的代碼使用sub緩衝區只爲響應消息,然後再釋放它。如果這將是您的代碼的最終行爲,您可以簡單地刪除malloc()free()調用,它可能會很好。

2

這聽起來像堆損壞我 - 你試過沒有/* -- Some Code -- */運行您的程序?

儘管您顯示的代碼看起來很好,但未顯示的代碼可能會在分配的內存之外覆蓋(損壞)堆的部分。雖然這可能不會導致內存損壞,並且在進程終止時不會導致失敗,但您可以非常容易地修改描述分配內存的數據結構,從而使調用free失敗。

更新:在你的第二個代碼展望張貼實際上可能是你無意中修改sub指針(又名堆棧損壞)的價值 - 可能通過寫過去的buf結束。這幾乎肯定會導致free失敗。

檢查撥號後malloc後面的sub的值,然後再次檢查free之前的值,以確保它沒有變化。

更新2: Scratch that - thkala有正確的答案。

+0

我確定我沒有訪問/ * --- Some Code - * /中的堆。我張貼相同的參考。 – 2010-12-08 08:01:29

0

因爲'sub'失去了malloc()結果地址的引用。首先,'sub'指向malloc()結果的開始地址。但是,當你使用'sub''正確拼寫'時,'sub'沒有指向malloc() - ed的內存。它成爲該字符串的起始地址 - 「Corr--」 - 。如果你使用'sub'來釋放malloc() - ed內存,編譯器會給你一個錯誤,因爲'sub'不指向malloc() - 編譯地址,並且你不能釋放字符串(char arrary) 。

你不要錯過,sub是指針值之一,而不是內存本身。