プロが教える店舗&オフィスのセキュリティ対策術

-------------------------------------------
class Myclass {
   int array[20];
public:
   Myclass() {
      for(int i=0; i<20; i++) {
         array[i] = 0;
      }
   }
};
--------------------------------------------

↑のようにするとarrayが初期化ではなく、代入されるそうなんですが、何か良い初期化方法があれば教えてください。

A 回答 (5件)

memsetによる初期化はいろいろ問題があるのでお勧めしませんが、int型の配列であれば実害はないので、状況次第では使ってもよいでしょう。



効率に関してですが、memsetの一般的な実装では、前後の半端を除けば、ワード単位で書き込みを行います。あるいは、ストリング命令やブロック転送命令があるプロセッサの場合は、最も効率のよいコードに展開されます(関数の呼び出しも発生しません)。

std::fillやstd::fill_nを使うと関数呼び出しのオーバーヘッドは発生しますので、効率のことをいうのであれば必ずしも最適ではありません。ただ、普通は一番よい選択だと思います。

いっそのこと、

class MyClass {
 struct Member { int array[20]; } m;
public:
 MyClass() : m(Member()) {}
};

のようにするのもよいと思います。
memsetよりはずっと健全ですし、STLが使えない場合でも大丈夫ですし、おそらくコンパイラは最も効率の良いコードを出力すると思います。
    • good
    • 0
この回答へのお礼

難しいですが面白い話です。ありがとうございます。

お礼日時:2009/10/30 20:42

STLのfill_nはどうでしょうか。



#include <algorithm>

std::fill_n(array, _countof(array), 0);
    • good
    • 0
この回答へのお礼

目からウロコです。ありがとうございます。

お礼日時:2009/10/30 13:35

処理系にもよりますが、この場合memsetの方が速いというのは幻想だと思います。



結局memset関数の中で、ループしてメモリを初期化しています。
しかも、memsetは、バイト単位の初期化になるため、
int20個の初期化は80回ループになります。
memset関数を呼び出すための関数呼び出しオーバーヘッドもあります。

処理系によっては、memsetをインラインで最適化して
処理してしまうケースもあると思いますが、
結局、質問に書かれているコーディングの通り、
int型変数(32ビット領域)に0を代入する処理を20回繰り返す処理を記述するのが
性能的に最も最適化されたコーディングだと思います。

ただ、memsetで初期化処理を記述する方がわかりやすいので、
メンテナンス性を考慮して、memsetにすべきという意見はあると
思います。私も特に性能を考慮する必要がない限りmemsetを使います。

今回のケースは、たいして複雑な初期化でもないし、
性能差もnsecレベルの話だと思うので、どちらでもよいと思います。
    • good
    • 0
この回答へのお礼

詳しく説明していただき分かりやすいです。参考になります。

お礼日時:2009/10/30 13:27

別に良いと思いますが、少しでも実行速度を上げたい場合は、mensetの方が良いと思います。


(自分でfor文で初期化すると少し実行速度が落ちます。)

memset(array,0,sizeof(array));
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。勉強になります。
memsetはレジスタでも使ってるんですかね?そのうち調べてみたいと思います。

お礼日時:2009/10/30 13:18

int型の配列であれば、代入になっても大差はないので、そのままでもよいのではないでしょうか?

    • good
    • 0
この回答へのお礼

私の中ではこのやり方に迷いが会ったのですが、おかげ様で自信が持てました。ありがとうございます。

お礼日時:2009/10/29 19:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!