2

私は単純なポインタ/キャストの問題で立ち往生しています:

pthread_create の pthread 関数に引数として 2 つの構造体の配列を渡そうとしています。コードは次のとおりです。

struct sockaddr_in addr_left, addr_right;
struct sockaddr_in* addr_vec [2] = {&addr_left, &addr_right};
pthread_create (&thread_forward,   NULL, thread_func_forward, (struct sockaddr**)addr_vec); 

内部 thread_func_forward:

void * thread_func_forward (void * argv) {
  struct sockaddr_in* addr_left = ((struct sockaddr_in*)argv + 0);
  struct sockaddr_in* addr_right = ((struct sockaddr_in*)argv + 1);
}

何らかの理由で正しく動作しません。プログラムはセグメンテーション違反なしで最後の行を実行できますが、構造体のメンバーにアクセスすると、それらは完全に変更されます

4

2 に答える 2

3

スレッド引数を正しい型にキャストしていません。あなたのコードはスレッド引数を a にキャストしますstruct sockaddr_in *が、それは正しい型ではありません。addr_vecはポインターの配列であるためaddr_vec、ポインターへのポインターに崩壊します。

ポインターへのポインターを渡しているため、スレッド関数でそのようにキャストする必要があります。次に、それを逆参照して、必要なポインターを取得する必要があります。

  struct sockaddr_in* addr_left = *((struct sockaddr_in**)argv + 0);
  struct sockaddr_in* addr_right = *((struct sockaddr_in**)argv + 1);

それらがスレッドを作成する関数からのローカル自動変数へのポインターであるという事実は、問題になる場合とそうでない場合があります。これらの変数がスコープ外になる前に、その関数がスレッドの完了を待機するかどうかによって異なります。

于 2013-06-29T10:05:27.860 に答える
1

あなたaddr_vecは自動ストレージ (つまりスタック上) に住んでいますが、変数の寿命が少なくともスレッド内でそれらにアクセスするポイントまで長く続くことを保証するための措置を講じたという兆候はありません。

つまり、スレッドを作成する前に動的に割り当ててからスレッド内で解放するか、同期プリミティブを使用して、スレッド自体でコピーを取得する前にスレッドを作成した関数が返されないようにする必要があります。

于 2013-06-29T10:04:07.503 に答える