ページ 11

構造体配列の初期化

Posted: 2010年8月29日(日) 06:45
by ニトロ
構造体配列の初期化は下のmemsetで正しいのでしょうか?
全て0埋めしたいです。
zeromemoryはつかわないものとします。
typedef struct{
    int a;
    int b;
}TEST;

TEST test[10];

memset( &test, 0, sizeof(test) );
memset( &test, 0, sizeof(test)*10 );

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 07:51
by へろりくしょん
これでいいと思いますよ。

ただ、構造体のメンバに実数型・ポインタ型が含まれている場合、不都合が生じる事もありますね。
これはmenset()固有の問題ではなく、すべてのビットを0でクリアするという仕様上の問題です。

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 07:54
by シエル
あれ?配列だから、&testの&はいらないんじゃ?

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 07:56
by シエル
memset( &test, 0, sizeof(test)*10 );

↑あとこれは10倍する必要ってありましたっけ?

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 07:59
by へろりくしょん
>あれ?配列だから、&testの&はいらないんじゃ?

あら。 そうですね。
思いっきり見逃していたようです。 失礼しました。


正解は、memset( test, 0, sizeof(test) );ですね。


memset( &test, 0, sizeof(test)*10 );
の場合は、test の型はTEST[10]ですので、*10はちょっとよろしくありませんね。
&も不要です。

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 09:29
by バグ
memset(test, 0, sizeof(TEST)*10);

こうしたかったのではないかと推測

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 09:34
by ニトロ
すみません(汗)
疑問に思って調べてみたのですが出てこなかったので
こちらにベタ書きして間違えておりました。
作っているソースでは&はついておりません。

>>正解は、memset( test, 0, sizeof(test) );ですね。
配列だからといって10倍しなくていいのですね。
勉強になりました。

みなさまご回答ありがとうございました。

>>バグ様
当たりですw
それも正しいのでしょうか?

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 13:21
by シエル
正しいです。

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 14:00
by フリオ
 
 初期化なら、

TEST test[10] = {0};

でいいのではないでしょうか。

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 14:16
by へろりくしょん
>TEST test[10] = {0};
>でいいのではないでしょうか。

そもそものスレッドの趣旨は
>全て0埋めしたいです。
ということですから、フリオさんの方法だとパティングの部分が0クリアされませんね。


追記です。

なんて書いておいて何ですが、パディングの中身を意識しなければならないようなコードは書くべきではありません。
アラインは処理系が都合上行うもので、プログラマが関知するべきではありません。
プログラマが扱うのはあくまでもメンバであるべきです。

画像

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 14:49
by たかぎ
CとC++では事情が異なりますね。
Cだと、初期化以外ではmemsetもやむを得ないでしょうが、C++だと、

std::fill_n(test, 10, TEST());

のほうがよい気がします。

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 15:43
by めるぽん
>ということですから、フリオさんの方法だとパティングの部分が0クリアされませんね。
初期化子を使って初期化した場合、指定していない領域が 0 で初期化されることは保証されています

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 16:05
by たかぎ
> 初期化子を使って初期化した場合、指定していない領域が 0 で初期化されることは保証されています

確実に初期化されるのは、部分オブジェクトだけですね。
詰め物は部分オブジェクトではないのでは?
C++の場合は、もっとはっきりと、「明示的に初期化されなかった各メンバ」と書かれていますね(8.5.1 集成体)。

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 16:12
by へろりくしょん
>初期化子を使って初期化した場合、指定していない領域が 0 で初期化されることは保証されています

最近の規格は知りませんが、本当にそうですか?

構造体の初期化子に省略されたメンバがある場合、それらのメンバは0で初期化されることが保証されていますが、構造体のすべてのビットが0で初期化される保証は無いと思うのですが。

Re:構造体配列の初期化

Posted: 2010年8月29日(日) 16:37
by めるぽん
ああ、ちゃんとパディング領域って書いてましたね、すみません。確かに構造体に対する初期化子だと無理そうです。
0埋めするのと全てのメンバを0初期化するのを混同してました。