2016-07-25 8 views
0

このプログラムは、コマンドラインから引数を取り、スレッドを使用して素因数を表示します。私はスレッド間の情報を渡すために構造体を使用しています。構造体には引数を保持する2D配列とその要素があります。私が今割り当てている方法は、私が私の議論のうちの2つにアクセスすることを可能にし、私にセグメンテーションフォールト(セグメンテーションフォールトの位置はコードに記載されています)を与えます。私は間違って何をしていますか?すべてのコードは以下のとおりです。私がテストしてきた2次元配列にメモリを割り当てる際のセグメンテーションフォルト

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

// Global variables 
#define MAX_FACTORS (11) 
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; 

struct Buffer { 
    int **factors; 
    int size; 
}; 


void *factor (void *buffer); 
void *displayFactors (void *factors); 


// MAIN 
int main (int argc, char* argv[]) { 
    // Create Buffer 
    struct Buffer *buffer; 
    buffer = malloc(sizeof(struct Buffer)); 
    buffer->size = argc - 1; 

    // Allocate memory for factors 2d array 
    buffer->factors = malloc(buffer->size); 

    for(int i = 0; i < buffer->size; i++) { 
     buffer->factors[i] = calloc(MAX_FACTORS, sizeof(int)); 
    } 

    pthread_mutex_lock(&mutex1); 

    if(buffer->size > 0) { 
     for(int i = 1; i < argc; i++){ 
      buffer->factors[i - 1][0] = atoi(argv[i]); 
      // ---SEGMENTATION FAULT OCCURS HERE AFTER LOOPING TWICE.---- 
     } 
    } 
    else 
     return 0; 

    pthread_mutex_unlock(&mutex1); 

    pthread_t producer; 
    pthread_t consumer; 

    pthread_create(&producer, NULL, factor, (void*)buffer); 
    pthread_create(&consumer, NULL, displayFactors, (void*)buffer); 

    pthread_join(producer, NULL); 
    pthread_join(consumer, NULL); 

    free(buffer->factors); 

    return 0; 
} 


// PRODUCER 
void *factor (void *buffer) { 
    struct Buffer *prod_buffer = (struct Buffer*)buffer; 

    pthread_mutex_lock(&mutex1); 

    // find numbers to factor factors 
    int i = 0; 
    while(i < prod_buffer->size) { 
     // printf("Numbers to factor: %d\n", prod_buffer->factors[i][0]); 
     prod_buffer->factors[i][0] = prod_buffer->factors[i][0]; 
     i++; 
    } 

    // Factor numbers 
    for(int i = 0; i < prod_buffer->size; i++) { 
     int j = 1; 
     int toFactor = prod_buffer->factors[i][0]; 
     while(toFactor % 2 == 0) { 
      prod_buffer->factors[i][j] = 2; 
      toFactor = toFactor/2; 
      j++; 
     } 
     for(int k = 3; k <= toFactor; k += 2) { 
      while (toFactor % k == 0) { 
       prod_buffer->factors[i][j] = k; 
       toFactor /= k; 
       j++; 
      } 
     } 
    } 
    pthread_mutex_unlock(&mutex1); 
    return NULL; 
} 


// CONSUMER 
void *displayFactors (void *buffer) { 
    struct Buffer *cons_buffer = (struct Buffer*)buffer; 

    for (int i = 0; i < cons_buffer->size; i++) { 
     printf("%d: ", cons_buffer->factors[i][0]); 
     for (int j = 1; j < MAX_FACTORS; j++){ 
      if(cons_buffer->factors[i][j] != 0) printf("%d ", cons_buffer->factors[i][j]); 
     } 
     printf("\n"); 
    } 
    return NULL; 

} 

EDIT--引数は結果が表示されるはず4、13、46、72、5、および12である: 4:2 2 13:13 46: 2 23 72:2 2 2 3 3 5:5 12:助けのために2 2 3

ありがとう!

+0

問題を見つけるのに役立つデバッガを使用しましたか?少なくとも、どのコード行がsegフォールトを引き起こしているかを正確に教えてくれます。そして、関連する変数の状態を調べることで、その時点でさらに調査することができます。 – kaylum

+0

while(toFactor%2 == 0) 'です。それはinfineteループかもしれないように見えます。 'toFactor = toFactor/2;'は整数除算であり、常に 'toFactor'値になります。これは常に2の倍数になります。したがって、'(toFactor%2 == 0) 'は常にtrueになります。 – kaylum

+1

まあ、 'displayFactors()'はバッファにアクセスするためにミューテックスをロックしていないので、引き続きファクタリング中に値を表示しようとしている可能性があります。また、 'main()' *はまだロックアウトする他のスレッドがないときにロックしますが、これは不要です。 'displayFactors()' *がmutexをロックした場合、2つのスレッドは基本的に連続して実行されます。これは、多かれ少なかれ作業が完了するまで他のスレッドをロックアウトするからです。消費者スレッドがデータを表示してからmutexをロックする前に?) – Dmitri

答えて

1

gdbを使用してコードをデバッグすると、buffer->factorsのサイズが8であることがわかりました。

あなたはこのsegmentation faultエラーが修正できる

buffer->factors = malloc(buffer->size*sizeof(int *)); 

を行う必要があります。

また、コードに別のバグがあります。最初にconsumerを実行すると、出力は空になるので、最初にproducerを実行するには、condを使用する必要があります。ここで

いくつかのヒントは:

pthread_cond_t product = PTHREAD_COND_INITIALIZER; /*global*/ 
pthread_cond_signal(&product); /*In factor function*/ 

displayFactorsは、ミューテックスを追加する必要があります。

/*in displayFactors function*/ 
pthread_cond_wait(&product, &mutex1); 

これらのステートメントをどこに置くかは、自分で判断する必要があります。 あなたを助けてくれることを願います。

+0

それ、ありがとう! –

+0

'sizeof(int *)'だけでなく '(int *)'でなければなりません。あるいは 'sizeof(* buffer-> factors)'です。 – immibis

+0

@immibisあなたは正しいです、私はその誤りのために非常に残念です。それを指摘してくれてありがとう。 –

関連する問題