
構造体のメンバを初期化したいのですが、
メンバ数が多いので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と表示されます。
また、構造体には自動的に初期化と解放するための、
コンストラクタ・デストラクタのみがあり、
関数や仮想関数などの実装はありません。
この方法の安全性について、
ご存知の方がいらっしゃればアドバイスいただけると助かります。
よろしくおねがいします
No.2ベストアンサー
- 回答日時:
> memsetやZeroMemoryなどで可能だということが解りました。
以下参考にどうぞ。
http://www.kijineko.co.jp/tech/superstitions/ini …
わたしなら
typedef struct tagHoge {
char a;
int b;
int c;
float d;
}HOGE;
HOGE Huga = {0};
ですが。
なるほど、memsetは期待した結果にならないことがあるので、
危険ということですか。
ご提示いただいたURLのコメント欄に
>VC++だと
>A a[10] = { 0 };
>も結局memset呼ぶ出しになるんですよね
いくつか気になる点はありましたが・・・
少なくともmemset等を直接呼ぶよりいくつも安全そうです。
こちらの方法を参考にさせていただきたいと思います。
ありがとうございます。
No.3
- 回答日時:
> >VC++だと
> >A a[10] = { 0 };
> >も結局memset呼ぶ出しになるんですよね
> いくつか気になる点はありましたが・・・
それはコンパイラがそういうコードを出力しているわけですから問題ありません。
内部の事情を把握しているコンパイラが内部的な都合でmemsetを使うのと、内部の事情に依存せずにソースコードレベルで記述するのでは、まったく話が異なります。
No.1
- 回答日時:
処理系を特定することなく「安全性」を議論するわけですから, 「規格に従うすべての処理系で安全か, あるいはそうでないか」ということを念頭に置けばいいですか?
それを前提にしますが, デストラクタを定義してしまうと「C互換型 (POD)」にならないので memset 自体が危険だと思います. 規格上「C互換型のオブジェクトは, 一連のバイトからなる記憶域を占める」とありますが, 逆に読むと「C互換型でない型のオブジェクトは一連のバイトからなる記憶域を占めるとは限らない」となります.
以下余談をいくつか:
・その例ってコンパイルできないのでは? そもそも C++ でそのような typedef が「どうしても必要」な場面って想定しづらいんだけど.
・「どのような値で初期化したいのか」が分からないのに「memset なり ZeroMemory なりで初期化できるか」と言われても困る.
・文面上同じように「0 で初期化している」場合であっても, ビットパターンは型によって違う可能性がある. 例えば浮動小数の「0.0」やぬるポインタが「すべてのビットが 0」という表現を持つかどうかは処理系に依存する.
>その例ってコンパイルできないのでは?
>>ZeroMemory( this, sizeof(Sample) );
ZeroMemory( this, sizeof(SAMPLE) );
でした。凡ミスです、申し訳ないです。
PC用でのアプリなのでC++になります。
Cであれば struct SAMPLE sample;
のように宣言しなければならないですが、
C++であればtypedefがなくても宣言できましたね。
本題に戻りまして、
つまり安易にこのような方法は使わない方がよい、
ということでしょうか。
仕事等で使う物ではないのでCとの互換性は考慮しないとしても、
処理系に依存するのであれば、
今の自分の環境では動くから大丈夫だろう・・・
みたいな不安要素は原因不明なバグの元なので、
出来る限り取り除いておきたいものです。
(いつ開発環境や仕様が変わるかわからないものでもありますし)
とりあえずこの方法は使わないようにします。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- UNIX・Linux bashの変数でブランクがあるかチェックする方法教えて下さい。 3 2023/04/06 16:09
- Windows 10 bash の -z オプションがうまく動作しない原因を教えて下さい。 4 2023/03/22 18:04
- Excel(エクセル) 日本情報処理表計算について。 4 2022/08/28 21:46
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- ノートパソコン 初期化する方法を教えて欲しい。 2 2023/01/06 14:49
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
「#undef」と「#define」の使い...
-
Integer変数をカラにしたいので...
-
構造体のデータを丸ごとコピー...
-
C言語 構造体の中に共用体を定...
-
構造体の初期化方法について
-
整数から16進数への変換 現在c...
-
日付チェック関数について
-
構造体のポインタにNULLが入らない
-
typedefをプログラム中で解除す...
-
構造体のメモリの確保のされかた
-
VBAの変数のデータ型を変更する...
-
値が代入されてない時
-
変数の初期化について
-
ユーザー定義型変数の一括初期化
-
異なる構造体のデータのコピー
-
*s.pstrと*(s.pstr)は同じですか?
-
C++ 構造体の一括初期化 {0}
-
charとucharの違い
-
VBAで符号無し整数
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Integer変数をカラにしたいので...
-
VBAのプログラムで、DIAG = 1# ...
-
「#undef」と「#define」の使い...
-
C++ 構造体の一括初期化 {0}
-
構造体のデータを丸ごとコピー...
-
long型のデータをバイト型の配...
-
VBAにてcolorindexを変数に格納...
-
C言語 構造体の中に共用体を定...
-
VBAの変数のデータ型を変更する...
-
VBAで符号無し整数
-
typedefをプログラム中で解除す...
-
構造体のポインタにNULLが入らない
-
変数の初期化について
-
値が代入されてない時
-
charとucharの違い
-
構造体の初期化方法について
-
整数から16進数への変換 現在c...
-
命名規則 VB 構造体
-
日付チェック関数について
-
1バイトデータの読み出しについて
おすすめ情報