• ベストアンサー

構造体のデータを丸ごとコピーしたい

C言語の構造体の勉強をしています。 構造体のデータを丸ごとコピーしたいのですが、今までは下記プログラムの★1の方法で1つ1つやっていました。 しかし変数が増えてきたのでできれば一度にコピーをしたいのですが、★2の方法では場合によってはゴミが含まれてしまいます。 そこで★3の方法で試すと今のところコピーできたのですが、これは安全なのでしょうか? ご存知の方がおられればお願いします。 また、もっといい方法があればご伝授いただけると助かります。 #include <stdio.h> #include <string.h> struct Sample{  int val1;  int val2; }; void test(Sample *p, int num){  Sample d;  switch(num){  case 1: //★1   d.val1 = p->val1;   d.val2 = p->val2;  break;  case 2: //★2   memcpy(&d, p, sizeof(Sample));   break;  case 3: //★3   d = *p;   break;  }  printf("val1:%d, val2:%d\n", d.val1, d.val2); } int main(){  Sample s;  s.val1 = 1;  s.val2 = 2;  test(&s, 1);  return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.6

Cであれば、★2でも★3でも問題ありません。 ★2の方法では、パディング部分の不定値もそのままコピーしますが、そもそもパディング部分にアクセスしたり、ましてやその値に依存したコードを書くこと自体間違っていますので、何の問題もありません。 ところで... >  Sample s; という宣言を見る限り、(structが省略されているので)C++ではないかと思います。 C++の場合、memcpyで構造体をコピーできるのはC互換型(POD型)に限られます。その他のクラス(構造体を含む)をmemcpyでコピーすることはできません。 そのため、常に★3の方法を採用する方が無難です。 なお、構造体のメンバにポインタや参照を含む場合には、その参照先までコピー(すなわちディープコピー)を行うには、適切な代入演算子を定義する必要があります。 C++ではなくCの場合、専用のコピー関数を作るなどして対応する必要があります。

その他の回答 (5)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.5

★2でもコピーできると思ったんですけどゴミってなんでしょう ★2は関数呼ぶ分だけ手間がかかりますが結果は★3と同じだと思うんですが

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

sizeof は「実際にメモリ上で構造体が占めるバイト数」を返します>#2. つまり, アラインメントの都合上パディングが入る場合には, そのパディングも含めたバイト数になります. じゃないと配列を動的に確保できない.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ISO の規格に従っている処理系なら ★3 でコピーできることが保証されています.

  • arain
  • ベストアンサー率27% (292/1049)
回答No.2

★3でとくに問題はないです。 >★2の方法では場合によってはゴミが含まれてしまいます。 どの部分にゴミが入るかが記載されていませんが、構造体をmem系のAPIで扱うことはあまりよろしくありません。sizeof()を使用する場合も注意が必要です。 細かい理由は省きますが、「構造体で定義されているメンバの合計Byte数」=「実際にメモリ上に展開されている構造体のByte数」にはならないためです。 詳しいことは「構造体」「アライメント」「パディング」で調べてみてください。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

★3が一般的な方法だと思います 問題はないはずです

関連するQ&A