0

私は次のように割り当てられた構造を持っています:

static struct cparray_buffer_t *_cparray;

struct __attribute__ ((__packed__)) cparray_buffer_t 
{
    u_int64_t buflen;
    u_char buf[buffersize];
}

.
.
.
_cparray = (struct cparray_buffer_t *)calloc(1024, sizeof(struct cparray_buffer_t);

そして後でプログラムで私はそのようにmemcpyをやろうとします

memcpy(_cparray[0].buf, test, buffersize);

そして、私はsigsegvを取得します

memcpy で正しく参照していますか?

編集: gdb では、配列を実際に使用するときに _cparray のアドレスが 0x0 のようです。_cparray にデータ ウォッチポイントを配置しようとしましたが、それを解放するものは何もありません。興味深いことに、&_cparray を監視すると、まだ有効なアドレスがありますが、*&_cparray は 0x0 です。

edit2: 違いがあるかどうかはわかりませんが、calloc はスレッド 1 にあり、segfault はスレッド 2 で発生しています。ただし、グローバルな統計はすべてのスレッドに表示されるという印象を受けました。これは正しいです?

ありがとう

何が起こっている?

_cparray のウォッチポイントからの出力は次のとおりです。

Old value = (struct cparray_buffer_t *) 0x284ba000
New value = (struct cparray_buffer_t *) 0x0
0x28102c83 in sem_init () from /lib/libc.so.7
4

1 に答える 1

0

グローバル変数は、静的かどうかに関係なく、すべてのスレッドから表示されます。staticキーワードは、ファイル内でのみ表示されるように、変数ファイルのスコープを指定するだけです。ファイル内でのみ表示されるため、変数を使用するコードは、それが定義されているファイル内にある必要があります。

私が見た問題の1つは、静的変数をヘッダーファイルに入れて、変数が複数のファイルに表示されることを期待している場合です。その結果、静的変数はヘッダーが含まれる各ファイルに複製され、静的変数のいくつかの異なるインスタンスが生成されます。これらは異なるメモリ位置であるため、さまざまなファイル間で共有されません。

これは、1つのスレッドがメモリ領域を作成し、2番目のスレッドがメモリ領域を使用するマルチスレッドアプリケーションであるため、最初のスレッドによって割り当てられる前に2番目のスレッドがメモリ領域にアクセスしている競合状態が発生する可能性があります。

まず最初に、ポインタを既知の値に初期化します。

static struct cparray_buffer_t *_cparray = 0;

次に、2番目のスレッドで、変数に0に対するチェックのあるアドレスがあるかどうかをテストできます。アドレスがゼロの場合は、スリープして、最初のスレッドがメモリを割り当てたことを意味するゼロ以外になるまで再試行します。推奨されるアプローチは、最初のスレッドがメモリを割り当ててから、2番目のスレッドを開始してメモリを使用することです。または、最初のスレッドがポインタを使用しようとする前に、最初のスレッドがメモリを割り当てるまで2番目のスレッドが待機している限り、他のスレッド同期を使用できます。

memcpy()関数呼び出しは、testが配列などのある種のポインターであると仮定すると、正しく見えます。コードは次のようになると思います。

u_char test[buffersize];
// do some things involving test

// save the things put into test
memcpy (_cparray[0].buf, test, buffersize);
于 2012-08-09T03:08:48.367 に答える