pthreads“double free or corruption(out)”错误

时间:2017-11-08 09:28:57

标签: c parallel-processing pthreads

我正在尝试使用pthreads进行矩阵乘法, 但不知怎的,我得到了“双重免费或腐败(失败)”错误。

typedef struct {
    double *my_x;
    double *my_y;
    double my_dot_prod;
    double *global_dot_prod;
    pthread_mutex_t *mutex;
    int my_vec_len;
} dot_product_t;

void *serial_dot_product(void *arg) {
    dot_product_t *dot_data;
    int i;

    dot_data = arg;

    for(i=0; i<dot_data->my_vec_len; i++)
        dot_data->my_dot_prod += dot_data->my_x[i]*dot_data->my_y[i];

    pthread_mutex_lock(dot_data->mutex);
    *(dot_data->global_dot_prod) += dot_data->my_dot_prod;
    pthread_mutex_unlock(dot_data->mutex);
    pthread_exit(NULL);
}

int main() {
    double *x, *y, dot_prod;
    pthread_t *working_thread;
    dot_product_t *thrd_dot_prod_data;
    void *status;
    pthread_mutex_t *mutex_dot_prod;

    int num_of_thrds;
    int vec_len;
    int subvec_len;

    double** A;
    double** B;
    double** C;

    int i=0;
    int j=0;
    int n;

    printf ("Enter matrix dimension n: ");
    scanf(" %d", &n);

// Matrix A - memory allocation
    A =(double **)malloc(n*sizeof(double *));
    A[0] = (double *)malloc(n*n*sizeof(double));
    A[0] = (double *)malloc(n*n*sizeof(double));
    if(!A) {
        printf("memory failed \n");
        exit(1);
    }
    for(i=1; i<n; i++) {
        A[i] = A[0]+i*n;
        if (!A[i]) {
            printf("memory failed \n");
            exit(1);
        }
    }

// Matrix B - memory allocation
    B =(double **)malloc(n*sizeof(double *));
    B[0] = (double *)malloc(n*n*sizeof(double));

    if(!B) {
        printf("memory failed \n");
        exit(1);
    }

    for(i=1; i<n; i++) {
        B[i] = B[0]+i*n;
        if (!B[i]){
            printf("memory failed \n");
            exit(1);
        }
    }

// Matrix C - memory allocation
    C =(double **)malloc(n*sizeof(double *));
    C[0] = (double *)malloc(n*n*sizeof(double));
    if(!C) {
        printf("memory failed \n");
        exit(1);
    }

    for(i=1; i<n; i++) {
        C[i] = C[0]+i*n;
        if (!C[i]) {
            printf("memory failed \n");
            exit(1);
        }
    }

    for(i=0; i<n; i++) {
        for(j=0; j<n; j++) {
            A[i][j] = 1.0;
            B[i][j] = 1.0;
            C[i][j] = 0.0;
        }
    }

    printf("Number of processors = ");
    if(scanf("%d", &num_of_thrds) < 1 || num_of_thrds > MAXTHRDS){
        printf("Check input for number of processors. Bye.\n");
        return -1;
    }
    printf("Vector length = ");
    if(scanf("%d", &vec_len)<1 || vec_len > n){
        printf("Check input for vector length. Bye.\n");
        return -1;
    }
    subvec_len = vec_len/num_of_thrds;

    working_thread = malloc(num_of_thrds*sizeof(pthread_t));
    thrd_dot_prod_data=malloc(num_of_thrds*sizeof(dot_product_t));
    mutex_dot_prod = malloc(sizeof(pthread_mutex_t));
    pthread_mutex_init(mutex_dot_prod, NULL);

    int k = 0;
    int l = 0;

    for(j=0;j<n;j++){
        for(k=0;k<n;k++){
            x = A[j];
            y = B[k];
            for(i=0; i<num_of_thrds; i++){
                thrd_dot_prod_data[i].my_x = x + i*subvec_len;
                thrd_dot_prod_data[i].my_y = y + i*subvec_len;
                thrd_dot_prod_data[i].global_dot_prod = &dot_prod;
                thrd_dot_prod_data[i].mutex = mutex_dot_prod;
                thrd_dot_prod_data[i].my_vec_len =
                        (i==num_of_thrds-1)?vec_len-(num_of_thrds-1)*subvec_len:subvec_len;
                pthread_create(&working_thread[i], NULL, serial_dot_product,(void*)&thrd_dot_prod_data[i]);
            }
            for(i=0; i<num_of_thrds; i++)
                pthread_join(working_thread[i], &status);
             C[j][k] = dot_prod;
            dot_prod = 0.0;

        }
    }

    for(i=0;i<n;i++) {
        for(j=0;j<n;j++){
            printf("%lf ", C[i][j]);
        }
        printf("\n");
    }

    free(A);
    free(B[0]);
    free(B);
    free(C[0]);
    free(C);
    free(x);
    free(y);
    free(working_thread);
    free(thrd_dot_prod_data);
    pthread_mutex_destroy(mutex_dot_prod);
    free(mutex_dot_prod);
}

serial_dot_product函数是我用于每个B矩阵的A矩阵和列上的每一行的函数,然后将得到的返回值分配给C [j] [k]。但是,当我运行此操作时,我收到此错误。 Error image

在实际的“双重免费或损坏”错误之前,它给出了一个矩阵,但这是错误的。

1 个答案:

答案 0 :(得分:1)

这里有几个问题。

您可以通过分配n来创建A元素数组。然后,您创建一个n元素的二维数组,并将其附加到A中的第一个元素。两次。 第一次分配丢失,并且是内存泄漏。

BC执行相同的操作,没有双重分配。

然后,您对ABC进行操作,就像它们是二维数组一样,它们不是,所以您要写入“随机”位置内存(即,没有分配内存的地方)正在破坏堆。 您应该将ABC分配为二维数组。

完成后,您不会释放A[0]数组,只释放A数组。 这会泄漏A [0]分配。在释放B[0]C[0]数组之前,您正确释放了BC数组。 然后你释放xy,它们从未被分配 - 它们只引用已分配的内存。 这是“双重免费”错误的来源。