3

こんにちは、C ポインター (特に void *) に関する質問があります。

Vector 実装のセルとして機能するメモリの任意のブロブを指す void * ポインターを使用しています。これらの BLOB はヒープに割り当てられます。

私の質問は、なぜ割り当て

    void *dest = CVectorNth(cv, i);
    void *src = CVectorNth(cv, i-1);
    *(void **)dest = *(void **)src;

その間働かない

    memmove(dest, src, elementSize);

動作します。

memmove を使用する必要があるのはなぜですか? 私の頭の中で、ポインターの値を src が指しているアドレスに変更しています。

私はmemmoveが正しい方法であることを知っていますが、今ではその理由さえ考えられません

    dest = src;

うまくいかない

4

6 に答える 6

4
*(void **)dest = *(void **)src;

destと の両方をへsrcのポインタとして解釈し、 where が指す場所から where が指す場所にバイトvoid*をコピーします。sizeof(void *)srcdest

memmove(dest, src, elementSize);

elementSizeバイトを wheresrcポイントから where ポイントに移動しますdest。場合elementSize == sizeof(void *)によっては、影響を受ける領域が重ならず、両方が適切に配置されていれば、両方とも同じ効果がsrcあります。1 つ目は、とdestのいずれかが適切に配置されていない場合、未定義の動作を呼び出します (影響を受ける領域が重なっている場合、少なくとも 1 つが適切に配置されていない可能性があります)。destsrc

特定のタイプがある場合は、適切なタイプにElementキャストするだけで済みます。destsrc

*(Element *)dest = *(Element *)src;

目的の効果を達成するために。

于 2013-05-23T09:58:31.703 に答える
4

*(void **)dest = *(void **)src; != memmove(dest, src, elementSize); 最初は単なる代入操作であり、memmove()メモリの内容をコピーsrcするため(destディープコピー)

編集

あなたのdestsrcがこのようなものだとします。

  src           5   6  7  8    
  +-----+      +--+--+--+---+
  | 5   +----->| A|B |C | D |
  +-----+      +--+--+--+---+

  dest          18  19 20 21  
  +-----+      +--+--+--+---+
  | 18  +----->|  |  |  |   |
  +-----+      +--+--+--+---+

さて、何*(void **)dest = *(void **)src;

好き

  src           5   6  7  8    
  +-----+      +--+--+--+---+
  | 5   +----->| A|B |C | D |
  +-----+      +--+--+--+---+

  dest          18  19 20 21  
  +-----+      +--+--+--+---+
  | 18  +----->| A|  |  |   |
  +-----+      +--+--+--+---+

代入により、ロケーション 5 のコンテンツ (* を使用するため) をロケーション 18 にコピーするためです。

*(void **)dest = *(void **)src;私の控えめな表現に何か問題があるため
、ここで ラースマンの答えを検討してください。

一方、次のように実行しmemmove(dest, src, elementSize);ます。

好き

  src           5   6  7  8    
  +-----+      +--+--+--+---+
  | 5   +----->| A|B |C | D |
  +-----+      +--+--+--+---+

  dest          18  19 20 21  
  +-----+      +--+--+--+---+
  | 18  +----->| A|B |C |   |
  +-----+      +--+--+--+---+

=としelementSizeます。3

memmove elementSizesrc から dest が指すメモリ領域に要素をコピーします (deepcopy)

好きなことでdest = src

  src           5   6  7  8    
  +-----+      +--+--+--+---+
  | 5   +----->| A|B |C | D |
  +-----+  --->+--+--+--+---+
           | 
  dest     |    18  19 20 21  
  +-----+  |   +--+--+--+---+
  | 5   +---   |  |  |  |   |
  +-----+      +--+--+--+---+

シャドウ コピー:

From:トーマス(ありがとう!)

より具体的には、後者の手法は「ポインタ スワッピング」として知られており、その用途はありますが、ディープ メモリ コピーとは直接互換性がありません (別の設計が必要です。特に、「スワップ」される 2 つのメモリ領域が永続的である必要があります)。 . ベクトル実装の場合、私たちのものになる可能性はほとんどありません

于 2013-05-23T09:49:34.213 に答える