2017-11-08 45 views
0

pthreads, 을 사용하여 행렬 곱셈을 시도하지만 어떻게 든 "이중 자유 또는 손상 (out)"오류가 발생합니다.pthreads "double free or corruption (out)"오류

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 함수 I 각 B 매트릭스의 행렬과 열을 각 행에 대해 사용하고 C [J] [K]에서 얻어진 결과 값을 할당하고있어 하나이다. 그러나 이것을 실행할 때이 오류가 발생합니다. Error image

실제 '이중 여유 또는 손상'오류가 발생하기 전에 볼 수있는 매트릭스를 제공하지만 잘못된 것입니다.

+0

Valgrind (메모리 문제는 memcheck, thread는 helgrind/DRD)에서 실행할 수 있습니까? –

+0

너무 오래 읽지 않았다면 자신의 프로그램을 디버깅하는 방법을 배워야합니다. – Stargateur

+0

@Stargateur 아 죄송합니다. 나는 조금 절망적이었다. 하루 종일 조사 중이 었는데 어떻게 든 대답을 찾지 못했습니다. 이것이 나의 최후의 수단이었다. – Alexis

답변

1

여기에 몇 가지 문제가 있습니다.

A을 할당하여 n 요소의 배열을 만듭니다. 그런 다음 n 요소의 2 차원 배열을 만들고 A의 첫 번째 요소에 연결합니다. 두번. 첫 번째 할당이 손실되고 메모리 누수입니다.

BC에 대해 똑같은 작업을 이중 할당없이 수행합니다.

은 그래서 당신은 메모리에서 "임의"장소 (즉이 아니라 당신이 메모리가 할당 된 경우)을 작성 그렇지 않은 두 가지 차원 배열을,있는 것처럼 그런 다음 A, BC에서 작동하는 힙을 손상시키고 있습니다. A, BC을 2 차원 배열로 할당해야합니다.

끝나면 배열 A 배열 A[0] 해제하지 마십시오. 이것은 A [0] 할당을 유출합니다.BC 어레이를 출시하기 전에 B[0]C[0] 어레이를 올바르게 비 웁니다. 그런 다음 xy은 할당되지 않았으며은 할당 된 메모리 만 참조합니다. 이것은 "double free"오류의 원인입니다.

+0

고맙습니다. 나는 자유 (x)와 자유 (y)를 없애 버렸다. 적절한 결과 행렬 곱셈을 적절하게 제공하기 위해 구현해야합니다. – Alexis

+0

내가 지적한 다른 오류가 수정 되었기를 바랍니다. StackOverflow가 작동하게 만드는 원인 중 일부인 문제를 해결할 때 응답을 "수락"으로 표시해야합니다. – FKEinternet