多线程程序中的双重自由或损坏

时间:2016-11-15 13:25:12

标签: c pthreads free

我遇到了问题

  <。>`。/ thread'出错:double free或corruption(out):0x00000000021bb030

我的程序的目的是输入:#of thread(argv [1])和读取data.txt 100整数和每个线程排序。现在

我的整个代码都在那里..

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *bubble(void *data){

    int * arr = data;   
    int i,j,tmp;
    int size = (sizeof(arr)/4);
    printf("%d",size);

    for(i=0;i<size;i++){
        for(j=0;j<size-1;){
            if(arr[j]>arr[j+1])
            {
                tmp = arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=tmp;
            }

        }

    }

    for(i=0;i<size;i++) printf("%d ",arr[i]);
        printf("\n");
    return ((void *)0);
}

int main(int argc, char **argv){

    FILE * fd;
    int data[100];

    int i,j;
    int tcount = atoi(argv[1]);
    int n = 100/tcount;
    int cursor=0;
    int err;


    pthread_t *thread_t = (pthread_t *)malloc(tcount* sizeof(pthread_t));

    int **data3 = (int **)malloc(tcount *sizeof(int*));
    for( i=0; i<tcount; i++)
        data3[i] = (int *)malloc((100/tcount) *sizeof(int));


    fd = fopen("data.txt", "r");

    printf("tcount = %d n=%d\n",tcount,n);
    for(i =0; i<100;i++)
    {
        fscanf(fd, "%d",&data[i]);
        printf("%d ", data[i]);
    }

    for(j=0;j<tcount;j++){
        for(i=0;i<n;i++){
            data3[j][i]=data[n*j+i];
            printf("%d ",data3[j][i]);
        }
        printf("\n");
    }


    for(i =tcount; i>0;i--)
    {
        err=pthread_create(&thread_t[i],NULL,bubble,(void *)&data3[i]);
            if(err != 0)
                printf("creat thread error");
    }




    for(int i=0; i<tcount; i++)
        free(data3[i]);
    free(data3);
    free(thread_t);
    fclose(fd);

}

1 个答案:

答案 0 :(得分:1)

您创建线程,然后立即开始释放线程使用的内存,而不等待它们退出。然后,您还可以在线程退出之前退出进程,并将其终止。

在清理和退出程序之前,您应该等待线程退出。您可以致电pthread_join

for(int i=0; i<tcount; i++)
    pthread_join(thread_t[i]);

正如评论sizeof(arr)中所述,不会给你数组的大小。它将为您提供指针的大小,而不是它指向的大小。

此外,您的线程创建循环首先超出界限,这将导致未定义的行为。最高索引为tcount - 1,最低索引为0

最后是几个小注释:首先是关于thread_t变量的命名。 _t后缀通常用于类型别名,例如pthread_t。虽然没有错,但可能会使读者对您的代码感到困惑。第二个是C中的空指针由NULL表示。不要使用(void *) 0(它不可移植)。