2013-02-19 2 views
0

Я объявила структуру и попыталась использовать элементы этой структуры в основной программе. Я не уверен, что это правильный подход. что может быть альтернативным подходом. Может ли оно объявлять новые матрицы и переменные в основном, а затем присваивать эти значения значениям struct. Я получаю все 0s в первой строке результирующей матрицы, но вторая строка вычисляется правильно. Также я должен динамически создавать потоки.Ошибка сегментации в многопоточной программе

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

struct v { 
int i; /* row */ 
int j; /* column */ 
    int M, N, K; 
float** A; 
float** B; 
float** C; 
}; 


void *runner(void *param); /* the thread */ 

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

    int c, d, k, sum = 0; 
pthread_t tid[50];  //Thread ID 
    int i,j, count = 0,thread_identifier,ret=5, count_dimension=0; 
    char ch; 
    struct v *data = (struct v *) malloc(sizeof(struct v)); 

    printf("Enter the number of rows and columns of first matrix\n"); 
    scanf("%d%d", &(data->M), &(data->K)); 
    (data->A) = malloc((data->M)*sizeof(float*)); 
    for (i =0;i < data->M; i++) 
(data->A[i]) =malloc((data->K)*sizeof(float)); 

    printf("Enter the number of rows and columns of second matrix\n"); 
    (data->B) = malloc((data->K)*sizeof(float*)); 
    scanf("%d%d", &(data->K), &(data->N)); 
    for(i=0;i<(data->K);i++) 
(data->B[i]) = malloc((data->N)*sizeof(float)); 

    printf("Allocate memory for result matrix \n\n"); 
    (data->C) = malloc((data->M)*sizeof(float*)); 
    for(i=0;i<(data->M);i++) 
    (data->C[i]) = malloc((data->N)*sizeof(float)); 

     printf("Enter the elements of first matrix\n"); 
     for(i = 0 ; i < data->M ; i++) 
     for (j = 0 ; j < data->K ; j++) 
     scanf("%f", &(data->A[i][j])); 

     printf("Enter the elements of second matrix\n"); 
     for(i = 0 ; i < data->K ; i++) 
     for (j = 0 ; j < data->N ; j++) 
      scanf("%f", &(data->B[i][j])); 



     for(i = 0; i < data->M; i++) 
    { 
    j=0; 

    data->i = i; 
    data->j = j; 
    /* Now create the thread passing it data as a parameter */ 

    pthread_attr_t attr; //Set of thread attributes 
    //Get the default attributes 
    pthread_attr_init(&attr); 
    //Create the thread 
    pthread_create(&tid[i],&attr,runner,data); 
//printf("create worker thread %u for row %d",(unsigned int)pthread_self(),i); 
printf("%lu",tid[i]); 
printf("\n"); 
    count++; 
} 

    for(i=0;i< data->M;i++) 
    {   

//Make sure the parent waits for all threads to complete 
    pthread_join(tid[i], NULL); 
    }  

    //Print out the resulting matrix 
    for(i = 0; i < data->M; i++) { 
    for(j = 0; j < data->N; j++) { 
    printf("%.2e ", data->C[i][j]); 
    } 
printf("\n"); 

    } 
    printf("\n"); 
    printf("%d",count); 
} 

    //The thread will begin control in this function 
    void *runner(void *param) { 
    struct v *data = param; // the structure that holds our data 
    int n,x=0, j=0; //the counter and sum 
    float sum = 0.00; 
    for(x=0;x<data->N;x++) 
    { 
for(j=0;j<data->N;j++) 
{ 
    sum += data->A[data->i][j] * data->B[j][x]; 
} 
data->C[data->i][x] = sum; 
sum=0.00; 
    } 

    //Exit the thread 
    //pthread_exit(0); 
    } 
+0

Во-первых, у Даниэля есть ответ, который * очень * вероятен в вашей ошибке. В прошлом я предполагаю, что ваше конечное намерение состоит в том, чтобы каждый поток выполнял отдельную пару строк/столбцов, так как сейчас они все бьют все и топают друг на друга. – WhozCraig

+0

Я пытаюсь создать поток для вычисления каждого вычисления строк. Я изменил это, и теперь он дает ошибку сегментации после печати идентификаторов потоков. Может быть, мне нужно выделить память для результирующей матрицы. как я могу остановить поток, поражающий все? – Learner

+0

Данные, относящиеся к потоку, должны содержать (a) указатели на все три матрицы и (b) конкретное число строк/столбцов, которое поток несет за размножение. Каждый поток, делая это, никогда не будет топать на любые данные, созданные другим потоком. Все ваши недостающие - это способ сообщить каждому потоку *, который * row/col устанавливает обработку. – WhozCraig

ответ

1
*(data->A) = malloc((data->M)*sizeof(float*)); 

должно быть

data->A = malloc((data->M)*sizeof(float*)); 

data->A находится в этой точке неинициализированного, поэтому разыменовании он вызывает неопределенное поведение. Кроме того, это float**, поэтому вы хотите, чтобы он указывал на массив float* s.

То же самое относится и к data->B, конечно. И вам также необходимо выделить память для data->C.

+0

О да, спасибо, но я получаю ошибку сегментации после печати идентификаторов потоков. Нужно ли выделять память для матрицы результатов и печатать их, чтобы исправить ее. – Learner

+0

Да, вам нужно выделить память для матрицы результатов. Печать идентификаторов потоков не должна иметь ничего общего с segfault, если только 'data-> M' больше 50. –

+0

Почему я часто сегментирую falut, а иногда получаю матрицу результатов с одной строкой 0 и другими правильными – Learner

Смежные вопросы