Reputation: 567
Say I want to compute the product of n complex numbers.
What I'm trying to do is that compute the product of the 2*i and 2*i+1 (i=0;i<n/2)
complex numbers in threads. ie, clump 2 numbers together and compute their product, therefore I shall get n/2 products. Then again perform the same action on these n/2 products. So on and so forth, and carry on till the value of n is 1.
Here's my code
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct complex{
int a;
int b;
};
struct complex arr[1000];
struct arg {
struct complex arr1;
struct complex arr2;
int i;
};
//struct arg *argv;
struct arg *argv=malloc(sizeof(struct arg));
void *multiplier(struct arg *argv)
{
int real,imaginary;
real=(argv->arr1.a)*(argv->arr2.a)-(argv->arr1.b)*(argv->arr2.b);
imaginary=(argv->arr1.a)*(argv->arr2.b)+(argv->arr1.b)*(argv->arr2.a);
arr[argv->i].a=real;
arr[argv->i].b=imaginary;
printf("real=%d imaginary=%d no=%d\n",real,imaginary,argv->i);
pthread_exit(0);
}
int main(void)
{
int n,i,j,flag=0,q;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d + i%d",&arr[i].a,&arr[i].b);
for(i=0;i<n;i++)
printf("%d + i%d\n",arr[i].a,arr[i].b);
while(n!=0)
{
if(n%2==1)
flag=1;
else
flag=0;
for(i=0;i<n/2;i++)
{
argv->arr1.a=arr[2*i].a; /* SEG FAULT HERE */
argv->arr1.a=arr[2*i].b;
argv->arr2.a=arr[2*i+1].a;
argv->arr2.a=arr[2*i+1].b;
argv->i=i;
pthread_create(&tid,&attr,multiplier,(void *) argv);
}
pthread_join(tid,NULL);
if(flag==1)
{
arr[n/2].a=arr[n-1].a;
arr[n/2].b=arr[n-1].b;
}
n=n/2;
}
return(0);
}
However my code gives me seg fault at line 45. I've been trying to figure out what's wrong with it but to no avail. I probably might be making a fundamentally horrendous error, but do help me out.
EDIT 1: Probably the most stupid error ever. I can't allocate memory globally like the way I just did.
I just inserted the Malloc into the main function and the program works.
Upvotes: 3
Views: 173
Reputation: 70971
Each thread needs it's own memory passed in via argv
to not overwrite the other thread data.
So you might liek to move this line
struct arg * argv = malloc(sizeof(struct arg));
to here:
for(i = 0; i < n/2; ++i)
{
struct arg * argv = malloc(sizeof(*argv));
argv->arr1.a = arr[2*i].a;
Also checking the result of the calls malloc()
might not be a bad idea.
Then let the thread function free()
its memory when its done with it:
void * multiplier(struct arg * argv)
{
...
free(argv);
pthread_exit(0);
}
Also the thread function to be passed to pthread_create()
is defined as:
void *(*)(void *)
So you shall declare yours this way:
void * multiplier(void * pvargv)
{
struct arg * argv = pvargv;
...
Upvotes: 2
Reputation: 143189
First, I'm not sure if the memory size you allocate for argv
is sane enough. Second, you modify this argv
thing, create a thread and immediately overwrite it, probably, before the thread even gets its hands on it.
Upvotes: 0
Reputation: 399949
It's pretty hard to figure out which of your lines is line 45.
Also, this looks very wrong:
struct arg *argv=malloc(5*sizeof(struct complex));
It's very rarely correct to mis-match types like that, and struct complex
looks nothing like struct arg
, so this really seems strange. Also, you shouldn't have a global named argv
while u
Upvotes: 1