質問に暗示されている重要な点を見逃してしまい、それが見当たらない場合は、お詫び申し上げます。しかし、この中心線に関して:
std::auto_ptr<Base> p(new((void*)(new char[size])) Packet());
これは私がそれについて言うことができると思うことです:
最後のコンストラクター呼び出しは、Packet
ではなくPacket()
、である必要がありますが、実際にはコンパイラーはそれをそのまま受け入れる可能性があり、違いはない可能性があります
内部割り当てnew char[size]
では、配列アロケータを使用しますnew []
。CPPリファレンスは次の式について述べていますnew [array_n]
。
コンパイラによってエンコードされた追加情報(配列内のオブジェクトを適切に破棄するためにこの情報が必要なため、配列のサイズなど)が原因で、size_of(type)*array_nより多くが割り当てられる場合があることに注意してください。
ここで、外部アロケータ呼び出し、は、配置newnew ((void*)(...))
のインスタンスであり、ここでは次のように説明されています。
void* operator new ( std::size_t, void* ptr );
何もせず、ptrを返します。
つまり、を呼び出すnew []
と、コンパイラが配列で厳密に必要とされるよりも多くのメモリを割り当て、サイズ関連の情報を余分なスペースにエンコードする場合があります。ただし、新しい配置は「何も」行わないため、いかなる方法でも処理したり、余分な情報を削除したりすることはありません。
ただし、の使用は、を使用して(ではなく)を使用して割り当て解除が実行されることをstd::auto_ptr
意味するため、余分な情報が適切に割り当て解除されず、メモリリークまたはさらに悪い結果が生じる可能性があります。delete
delete []
編集: CPP参照のみに依存することを避けるために、C++標準N3337の関連部分は次のとおりです。
- §18.6.1.2は、
delete
によって割り当てられたスペースの割り当てを解除するためにのみ使用されnew
、それに応じdelete []
てによって割り当てられたスペースに使用されると述べていますnew []
- §18.6.1.3は、配置フォームがアクションを実行しないことを明示的に示して
new
いnew []
ます。これは、どちらも単一オブジェクト空間を配列空間に「変換」するために使用できないことを意味します。
おそらく本当の問題は、質問で新しく提案された配置の適用が、delete []
後でスペースの割り当てを解除するためにのみ使用された場合に有効であるかどうかです。おそらく答えは未定義です(これは「いいえ」と同等と解釈されるべきです)。