C++プログラムのコツ
巨大な配列はヒープ領域に確保する
Good
|
Bad
|
int* array = new int[1000000];
|
int array[1000000];
|
プログラムが利用するメモリには、new/delete(malloc/free)で確保されるヒープ領域と、関数呼び出しや変数の利用で確保されるスタック領域があります。スタック領域は1MB程度しかないので、大きな配列を確保するとすぐにStack overflow errorを起こします。大きな配列はnewで確保しましょう。
イテレータのインクリメントは前置にする
Good
|
Bad
|
vector<string> V;
:
for(vector<string>::iterator itr=V.begin();
itr != V.end(); ++itr)
cout << *itr << "\n";
|
vector<string> V;
:
for(vector<string>::iterator itr=V.begin();
itr != V.end(); itr++)
cout << *itr << "\n";
|
基本データ型でない場合、インクリメント演算子の定義は以下のようになります。戻り値の型に注意してください。後置オペレータは処理の後にインクリメントするため、返り値がインクリメントする前の状態にしないといけません。
iterator operator++(int)
{ //後置
iterator _Tmp = *this;
++*this;
return _Tmp;
}
iterator& operator++()
{ //前置
++*this;
return *this;
}
|
このためオーバーロードする関数の中でコピーコンストラクタによるオブジェクトの作成と、作成したオブジェクトを戻す際に再びコピーと、余分にオブジェクトが作成されるのです。
こうした余分な処理を含まないため、前置インクリメントを使います。(ただし、基本データタイプについてはどちらでも同じです。)
改行はendlではなく、"\n"を出力する
Good
|
Bad
|
out << "\n";
|
out << endl;
|
endlを出力する操作は、out << "\n"; out.flush();と同じです。頻繁に利用する場合は、flushの分だけ前者のほうが効率が良くなります。