2010-12-08 19 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是指针值之一,而不是内存本身。