• ベストアンサー

構造体のメンバ初期化について

構造体のメンバを初期化したいのですが、 メンバ数が多いので1個ずつ初期化するのは面倒です。 そのため、一度に初期化する方法を探していたのですが、 memsetやZeroMemoryなどで可能だということが解りました。 しかし、パディング等の問題を含めて この関数を使用しても問題ないのでしょうか? 以下に例を挙げます。 typedef struct SAMPLE {  char a;  int b;  int c;  float d;  SAMPLE(){   ZeroMemory( this, sizeof(Sample) );  } } Sample; 構造体Sampleは32bitマシンでは 一見13byteに見えますが、パディングが入るので、 実際にはsizeof(Sample)は16byteと表示されます。 また、構造体には自動的に初期化と解放するための、 コンストラクタ・デストラクタのみがあり、 関数や仮想関数などの実装はありません。 この方法の安全性について、 ご存知の方がいらっしゃればアドバイスいただけると助かります。 よろしくおねがいします

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

  • ベストアンサー
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.2

> memsetやZeroMemoryなどで可能だということが解りました。 以下参考にどうぞ。 http://www.kijineko.co.jp/tech/superstitions/initialization-by-memset.html わたしなら typedef struct tagHoge {  char a;  int b;  int c;  float d; }HOGE; HOGE Huga = {0}; ですが。

hiroko_ss
質問者

お礼

なるほど、memsetは期待した結果にならないことがあるので、 危険ということですか。 ご提示いただいたURLのコメント欄に >VC++だと >A a[10] = { 0 }; >も結局memset呼ぶ出しになるんですよね いくつか気になる点はありましたが・・・ 少なくともmemset等を直接呼ぶよりいくつも安全そうです。 こちらの方法を参考にさせていただきたいと思います。 ありがとうございます。

その他の回答 (2)

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

> >VC++だと > >A a[10] = { 0 }; > >も結局memset呼ぶ出しになるんですよね > いくつか気になる点はありましたが・・・ それはコンパイラがそういうコードを出力しているわけですから問題ありません。 内部の事情を把握しているコンパイラが内部的な都合でmemsetを使うのと、内部の事情に依存せずにソースコードレベルで記述するのでは、まったく話が異なります。

hiroko_ss
質問者

お礼

なるほど、 処理系によっては安全性が保障されているわけだから、 memsetが使われてるわけですね。 ありがとうございます。

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

処理系を特定することなく「安全性」を議論するわけですから, 「規格に従うすべての処理系で安全か, あるいはそうでないか」ということを念頭に置けばいいですか? それを前提にしますが, デストラクタを定義してしまうと「C互換型 (POD)」にならないので memset 自体が危険だと思います. 規格上「C互換型のオブジェクトは, 一連のバイトからなる記憶域を占める」とありますが, 逆に読むと「C互換型でない型のオブジェクトは一連のバイトからなる記憶域を占めるとは限らない」となります. 以下余談をいくつか: ・その例ってコンパイルできないのでは? そもそも C++ でそのような typedef が「どうしても必要」な場面って想定しづらいんだけど. ・「どのような値で初期化したいのか」が分からないのに「memset なり ZeroMemory なりで初期化できるか」と言われても困る. ・文面上同じように「0 で初期化している」場合であっても, ビットパターンは型によって違う可能性がある. 例えば浮動小数の「0.0」やぬるポインタが「すべてのビットが 0」という表現を持つかどうかは処理系に依存する.

hiroko_ss
質問者

お礼

>その例ってコンパイルできないのでは? >>ZeroMemory( this, sizeof(Sample) ); ZeroMemory( this, sizeof(SAMPLE) ); でした。凡ミスです、申し訳ないです。 PC用でのアプリなのでC++になります。 Cであれば struct SAMPLE sample; のように宣言しなければならないですが、 C++であればtypedefがなくても宣言できましたね。 本題に戻りまして、 つまり安易にこのような方法は使わない方がよい、 ということでしょうか。 仕事等で使う物ではないのでCとの互換性は考慮しないとしても、 処理系に依存するのであれば、 今の自分の環境では動くから大丈夫だろう・・・ みたいな不安要素は原因不明なバグの元なので、 出来る限り取り除いておきたいものです。 (いつ開発環境や仕様が変わるかわからないものでもありますし) とりあえずこの方法は使わないようにします。 ありがとうございます。

関連するQ&A