2017-11-08 5 views
0

Ich versuche, Matrix-Multiplikation mit Pthreads, , aber irgendwie bekomme ich "doppelt frei oder Korruption (out)" Fehler.Pthreads "doppelt frei oder Korruption (out)" Fehler

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 Die Funktion ist die, die ich bin für jede Zeile auf der A-Matrix und Spalte auf jeder B-Matrix und weise den resultierenden Rückgabewert auf C [j] [k] unter Verwendung. Wenn ich das jedoch ausführe, erhalte ich diesen Fehler. Error image

Es gibt mir eine Matrix, wie Sie vor dem eigentlichen "Doppel kostenlos oder Korruption" Fehler sehen können, aber es ist falsch.

+0

Können Sie dies unter Valgrind ausführen (Memcheck für die Speicherprobleme und Helgrind/DRD für Threads)? –

+0

zu lange nicht gelesen, sollten Sie lernen, wie Sie Ihr eigenes Programm debuggen. – Stargateur

+0

@Stargateur Ah Entschuldigung. Ich war nur ein bisschen verzweifelt. Ich recherchierte den ganzen Tag und irgendwie fand ich keine Antwort. Das war meine letzte Zuflucht. – Alexis

Antwort

1

Hier gibt es mehrere Probleme.

Sie erstellen ein Array von n Elementen durch Zuweisen von A. Dann erstellen Sie ein zweidimensionales Array von n Elementen und verbinden es mit dem ersten Element in A. Zweimal. Die erste Zuweisung ist verloren und ist ein Speicherleck.

Sie tun das gleiche für B und C, ohne die doppelte Zuordnung.

Sie arbeiten dann auf A, B und C, als ob sie zweidimensionale Arrays sind, was sie nicht sind, so schreiben Sie an „random“ Orte im Speicher (dh nicht in dem Sie Speicher zugewiesen haben), die korrumpiert den Haufen. Sie sollten A, B und C als zweidimensionale Arrays zuweisen.

Wenn Sie fertig sind, befreien Sie nicht das A[0] Array, nur das A Array. Dadurch wird die A [0] -Zuweisung verloren. Sie geben die Arrays B[0] und C[0] korrekt frei, bevor Sie die Arrays B und C freigeben. Dann frei x und y, die nie zugeteilt wurden - sie beziehen sich nur auf zugewiesenen Speicher. Dies ist die Quelle Ihres "doppelten kostenlosen" Fehlers.

+0

Danke. Ich nahm das freie (x) und freie (y) weg und es funktionierte. Ich muss es einfach implementieren, um mir die richtige Matrixmultiplikation zu geben. – Alexis

+0

Ich hoffe, Sie haben die anderen Fehler behoben, auf die ich hingewiesen habe. Sie sollten Antworten auch als "akzeptiert" markieren, wenn sie Ihre Probleme lösen, das ist ein Teil dessen, was StackOverflow funktioniert. – FKEinternet

Verwandte Themen