placement new(確保済みアドレスを指定する)について
placement newという通常のnewと異なるメモリアロケート方法があり、
通常のnewに比べて、以下の利点がある。
・メモリアロケートの時間が短縮される
・メモリアロケートの例外が発生しないように制御できる
■使い方
通常のnewと違い明示的にデストラクタを呼ぶ必要があります。
#include <cstdlib> #include <cstdio> #include <iostream> class Sample { char a[256]; }; int main() { //①メモリアロケート char* p_memory = new char[1024]; //②オブジェクトの初期化 Sample* p = new(p_memory) Sample(); //③オブジェクトの破壊 p->~Sample(); //④メモリ解放 sth::operator delete(p, p); return 0; }
最後に利点について補足します
・メモリアロケートの時間が短縮される
通常newの処理はざっくりいうと、使用できるメモリを探す→オブジェクトへ割り当る→コンストラクタで初期化
初めの、使用できるメモリを探す処理は結構ややこしく、メモリの断片化を防ぐために効率よくメモリ配置が行わ
れるため、時間がかかります。
確保済みアドレスを指定する場合は、①のメモリアロケートを事前に行うことで、
その後の処理時間を短縮できます。
・メモリアロケートの例外が発生しないように制御できる
①のメモリアロケートを事前に行い成功すると、②の処理で失敗することはない。
(失敗する理由がない、また、C++14から例外投げないことが明示されたと思います)
このことからシステム設計段階で各モジュールが利用できるメモリサイズを決めて置くと、
以下のことができます。
・システム起動時にメモリ確保
→普通成功する。万が一失敗した場合は、システム自体起動しない。
・実行中のnewの処理でplacement newを使用していると、実行時にエラーが
発生しない。
→メモリアロケート失敗時のめんどくさい例外処理を考えなくてよい
これを戦闘機のシステムのように実行時エラーが許されない(実行時エラー起こしたら墜落します)
ものに適用すると、リスクが減らせるから推奨されるようです。
確かF35から適用されたコーディングルールには適用されていたかと思う。
http://www.stroustrup.com/JSF-AV-rules.pdf