0

次のコードを実行しました。

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

struct foo
{
   int a;
   int b;
};

void* thread_func1(void *arg)
{
   struct foo *temp = (struct foo*)malloc(sizeof(struct foo));

   temp->a = 10;
   temp->b = 20;

   pthread_exit(temp);
}

void* thread_func2(void *arg)
{
   pthread_exit((void*)100);
}

int main()
{
   pthread_t tid1, tid2;
   int err;
   struct foo *f;
   void *ret;

   err = pthread_create(&tid1, NULL, thread_func1, NULL);
   err = err | pthread_create(&tid2, NULL, thread_func2, NULL);

   if(err != 0)
   {
      perror("pthread_create()");
      exit(-1);
   }

   err = pthread_join(tid1, (void**)&f);
   if(err != 0 )
   {
      perror("pthread_join1");
      exit(-1);
   }

   printf("a = %d, b = %d\n", f->a, f->b); //Line1

   err = pthread_join(tid2, &ret);
   if(err != 0 )
   {
      perror("pthread_join2");
      exit(-1);
   }

   printf("ret = %d\n", *(int*)ret); //Line2

   return 0;

}

Line2 でセグメンテーション違反が発生します。Line2 の何が問題なのか

Line2 を

printf("ret = %d\n", (int)ret);

セグメンテーション違反はなく、正しい値 (つまり、100) が出力されます。変更が機能する理由がわかりません。ダブルポインターの使用に関して、私は間違った概念を持っていると思います。直してもらいたいです。

セグメンテーション違反の理由と、修正が機能する理由は何ですか?

4

4 に答える 4

3

これは、ポインターではなく実際の整数を返しているためですが、ポインターとしてアクセスします。

于 2012-06-07T09:57:36.260 に答える
2

スレッドから1つの数値を返します。最初のスレッドでは、その番号はstruct foo *です。したがって、あなたが言うなら

pthread_join(tid1, &ret);

次にret、そのポインタ(ダブルポインタではありません)が含まれます。

同様に、2番目のケースでは、100それがであるかのように見ているにもかかわらず、戻ってきますvoid *。それにもかかわらず、値はまだ100です!

したがって、あなたが書くとき

pthread_join(tid2, &ret);

retが含まれます100。これはポインタではなく、単なる整数です。そのため、にもキャストする必要がありますint

セグメンテーション違反が発生した理由は、を100として見てint *、それを逆参照しようとするためです。

于 2012-06-07T09:59:49.440 に答える
1

アドレスが 100 のポインターを逆参照しようとしているからです。

戻り値を見る代わりに、thread_funcs で割り当てたいものへのポインターを渡してはどうでしょうか? つまり、thread_func1() および thread_func2() の「void *arg」引数を使用します。

このような:

void* thread_func1(void *arg)
{
   struct foo **fooPtrPtr = (struct foo**) arg;
   *fooPtrPtr = (struct foo*)malloc(sizeof(struct foo));

   ...
}

void* thread_func2(void *arg)
{
   int *intPtr = arg;
   *intPtr = 100;
   ...
}

int main()
{
   pthread_t tid1, tid2;
   int err;
   struct foo *f;
   int ret;

   err = pthread_create(&tid1, NULL, thread_func1, &f);
   err = err | pthread_create(&tid2, NULL, thread_func2, &ret);
   ...
   printf("a = %d, b = %d\n", f->a, f->b); //Line1
   ...
   printf("ret = %d\n", ret); //Line2
   ...
}
于 2012-06-07T09:57:50.330 に答える
1

pthread_exit((void*)100);integer100がスレッドの終了ステータスになります。型キャストを悪用するだけなので、それvoid*がその型です。この値を取得したい場合は、メイン スレッドでも同じ型キャストの乱用を使用する必要があります。

int ret;
err = pthread_join(tid2, (void**) &ret);
// here you can work with ret as with any other integer

returnの代わりに使用することもお勧めしますpthread_exit。また、 を使用して動的に割り当てられたメモリmallocは、 を呼び出して解放する必要があることに注意してくださいfree。また、ここでの戻り値の型キャストmallocは冗長なので、省略できます。

この質問も役に立ちます:終了したらスレッドを閉じる

于 2012-06-07T10:03:33.980 に答える