5

私は構造を持っています

typedef struct my_s {

   int x;
   ...
} my_T;

my_t * p_my_t;

のアドレスを設定したいのですがp_my_tNULLこれまでのところ、これを実行しようとした方法は次のとおりです。

memset (&p_my_t, 0, sizeof(my_t*))

しかし、これは私には正しく見えません。これを行う正しい方法は何ですか?


質問の修正 - 根本的により複雑な質問をする:

これが私がやろうとしていることです:

  • A と B の 2 つのプロセス
  • Aのmalloc p_my_t、BにはN個のスレッドがあり、それにアクセスできます
  • A で削除を開始しますが、B のスレッドがまだ使用している可能性があるため、単純に解放することはできません。
  • したがって、関数を呼び出し、p_my_t のアドレスを B に渡して、そのアドレスを B で NULL に設定し、B の他のスレッドが使用できなくなるようにします。
  • Bからコールバックした後、Aのメモリを解放します

注意: プロセス間の共有メモリを介してメモリ割り当てを管理する標準的な方法はありません。何が起こっているのかについて、かなり慎重に考える必要があります。

4

9 に答える 9

21

memsetヌルポインターの表現であることが保証されていないすべてのビットがゼロにメモリが設定されるため、ヌルポインターの初期化には使用しないでください。次のようにしてください。

p_my_t = NULL;

または同等のもの:

p_my_t = 0;
于 2008-12-29T22:22:25.753 に答える
4

正確に何をしようとしていますか? p_my_tは既にポインターですが、メモリを割り当てていません。ポインターを NULL に設定する場合は、次のようにします。

p_my_t = NULL;

このポインターを逆参照しようとすると、セグメンテーション違反 (または Windows ではアクセス違反) が発生します。

ポインターが実際に何かを指すようになると (たとえばmalloc()、 a のアドレスを介して、またはそれに割り当てることによってstruct my_T)、適切memset()にそれを行うことができます。

memset(p_my_t, 0, sizeof(struct my_T));

これにより、構造全体がゼロになり、すべてのフィールドがゼロに設定されます。

于 2008-12-29T22:22:48.857 に答える
2

ポインタをnullに設定するための推奨コードは、0(ゼロ)を割り当てることです。Bjarne Stroustrupそれを行います:)とにかく、それはNULLと同じように表現力があり、マクロ定義に依存しません。

NULLはキーワードではなく、予約されておらず、再定義するのは混乱しますが、(スタイル以上に)すべきではないとは何も言っていないことに注意してください。同僚は、他の人のコードがどのように動作するかを確認するために、ヘッダーで0以外の何かにNULLを定義することについて冗談を言うことがよくあります。

今後の標準では、nullポインタを識別するためのより表現力豊かなnullptrキーワードがあります。

于 2008-12-29T23:02:13.380 に答える
2

私は多分あなたが欲しいと思います

extern void set_t_pointer_to_null(my_T *pp);

そして電話する

set_t_pointer_to_null(&p_my_t);

どこ

void set_t_pointer_to_null(my_T *pp) { *pp = NULL; }

これを行う関数を定義する価値があるかどうかはわかりませんが、これはあなたが尋ねようとしている質問に答えると思います.

于 2008-12-30T02:56:05.747 に答える
0

ありがとう、これが私がやろうとしていることです

  • AとBの2つのプロセス
  • A、Bのmalloc p_my_tにはN個のスレッドがあり、それにアクセスできます
  • Aで削除を開始しますが、Bのスレッドがまだ使用している可能性があるため、単純に解放することはできません。
  • したがって、関数を呼び出し、p_my_tのアドレスをBに渡して、そのアドレスをBでNULLに設定し、Bの他のスレッドが使用できないようにします。
  • Bからコールバックした後、Aのメモリを解放します
于 2008-12-29T22:39:09.417 に答える
0

あなたの返信(この投稿の他の場所)によると:

ありがとう、これが私がやろうとしていることです

  • AとBの2つのプロセス
  • A、Bのmallocp_my_tにはN個のスレッドがあり、それにアクセスできます
  • Aで削除を開始しますが、Bのスレッドがまだ使用している可能性があるため、単純に解放することはできません。
  • したがって、関数を呼び出し、アドレスをBに渡して、p_my_tそのアドレスをBでNULLに設定し、Bの他のスレッドが使用できないようにします。
  • Bからコールバックした後、Aのメモリを解放します

必要なのは、すべてのスレッドとプロセス間の何らかの形式の同期です。プロセス間でこのオブジェクトをどのように共有しているかはわかりませんが、共有メモリを使用していると思われます。

通常、共有ポインタクラス(Boostのshared_ptrクラスなど)を使用することをお勧めしますが、このシナリオでそれがどの程度うまく機能するかはわかりません。クラスがそれ自体の参照を追跡し、Boostクラスで使用できるように、クラスを微調整することを検討することをお勧めしますintrusive_ptr

このようにして、プロセスAはオブジェクトを単に忘れることができ、プロセスBが終了すると、のインスタンスはmy_T参照が残っていないことを認識し、それ自体をクリーンアップします。

同期は、my_T内部で参照を追加または削除するときにここで機能します(したがって、クリーンアップする必要があると思われるが実際にはまだ使用されている厄介な競合状態に遭遇することはありません)。

もう少し「クルーゲ」な感じのあるもう1つのアプローチはmy_T、「is-valid」フラグの各インスタンスに、それを使用するすべてのプロセス/スレッドが続行するかどうかを認識できるようにすることです。

Boostのさまざまなポインタクラスの詳細については、それらのドキュメントを確認してください。

于 2008-12-29T22:48:50.067 に答える
0

あなたのマルチスレッド コメントを読むと、あなたのタスクを達成するための安全なコード シーケンスはないと言わざるを得ません。一歩下がって、アルゴリズムを再検討する必要があります。

于 2008-12-30T03:44:54.027 に答える
0

あなたの更新によると、あなたが実際にやろうとしているのは、リソースへのアクセスを保護することです。つまり、プロセス間で共有される読み取り/書き込みロックを使用して、そのリソースへのptrを保護し、使用する前に.ptr.

  • 構造体を共有メモリに割り当てます。
  • 共有メモリ内の構造体に ptr を割り当てます。
  • 構造体への ptr へのアクセスを読み取り/書き込みロックで保護します。
  • プロセス A は、ptr と構造体を初期化または無効化するときに、ptr への WRITE ロックを取得する必要があります。
  • プロセス B は、ptr への READ ロックを取得し、構造体を使用する前に ptr が有効であることをテストする必要があります。
于 2008-12-30T18:43:36.473 に答える
0

私が正しく理解できれば、memset はあなたの問題を解決しません。A と B が別々のプロセスである場合p_my_t、プロセス A はプロセス B では異なる形式p_my_tになります。異なるプロセス間でポインターを渡すことはできません。2 つのプロセス (メッセージ キューなど) を同期させるために、ある種の IPC メカニズムを使用p_my_t = NULLし、memset の代わりに使用することをお勧めします。

于 2008-12-30T10:50:22.933 に答える