3

n 複素数の積を計算したいとします。

私がやろうとしているのは(i=0;i<n/2)、スレッドで 2*i と 2*i+1 の複素数の積を計算することです。つまり、2 つの数値をまとめてその積を計算すると、n/2 の積が得られます。次に、これらの n/2 製品に対して同じアクションを再度実行します。というように、n の値が 1 になるまで続けます。

これが私のコードです

#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);
}

しかし、私のコードでは 45 行目で seg fault が発生します。何が問題なのかを突き止めようとしましたが、役に立ちませんでした。私はおそらく根本的に恐ろしい間違いを犯しているかもしれませんが、私を助けてください.

編集 1: おそらくこれまでで最もばかげたエラーです。今のようにメモリをグローバルに割り当てることはできません。

Malloc をメイン関数に挿入しただけで、プログラムは動作します。

4

3 に答える 3

2

argv各スレッドは、他のスレッドデータを上書きしないように、経由で渡される独自のメモリを必要とします。

だからあなたはこの線を動かすために嘘をつくかもしれません

struct arg * argv = malloc(sizeof(struct arg));

ここまで:

for(i = 0; i < n/2; ++i)
    {
        struct arg * argv = malloc(sizeof(*argv));
        argv->arr1.a = arr[2*i].a; 

また、呼び出しの結果を確認することはmalloc()悪い考えではないかもしれません。


次に、スレッドfree()がそれを実行したときに、スレッドにそのメモリを機能させます。

void * multiplier(struct arg * argv)
{
    ...

    free(argv);

    pthread_exit(0);
}

また、渡されるスレッド関数pthread_create()は次のように定義されます。

void *(*)(void *)

したがって、次のように宣言する必要があります。

void * multiplier(void * pvargv)
{
    struct arg * argv = pvargv;
    ...
于 2012-11-08T11:02:53.497 に答える
1

どの行が 45 行目かを特定するのはかなり困難です。

また、これは非常に間違っているように見えます:

struct arg *argv=malloc(5*sizeof(struct complex));

このようにタイプのミスマッチが正しいことはめったになく、 のstruct complexようには見えないstruct argため、これは本当に奇妙に思えます。argvまた、 u の間にグローバルな名前を付けるべきではありません。

于 2012-11-08T10:47:13.800 に答える
0

まず、割り当てたメモリ サイズargvが適切かどうかわかりません。次に、これを変更argvし、スレッドを作成して、おそらくスレッドがそれを手に入れる前に、すぐに上書きします。

于 2012-11-08T10:47:17.867 に答える