placement new と delete Conundrum
C では、placement new 演算子を使用してメモリを割り当てるときに、適切な割り当て解除方法に関してジレンマが発生します。その記憶。考えられる 2 つの解決策を検討してみましょう:
解決策 1:
const char* charString = "Hello, World";
void *mem = ::operator new(sizeof(Buffer) strlen(charString) 1);
Buffer* buf = new(mem) Buffer(strlen(charString));
delete (char*)buf;
このソリューションは、文字ポインターとして割り当てられたメモリを削除しようとします。ただし、このアプローチは、オブジェクトのデストラクターを適切に処理したり、生のメモリの割り当てを解除したりしないため、正しくありません。
解決策 2:
const char* charString = "Hello, World";
void *mem = ::operator new(sizeof(Buffer) strlen(charString) 1);
Buffer* buf = new(mem) Buffer(strlen(charString));
delete buf;
この解決策でも、割り当てられたメモリの削除が試行されますが、Buffer* ポインターで削除演算子を直接呼び出します。これは、通常の new 演算子を使用してメモリが割り当てられた場合に機能します。ただし、新しい配置が使用されているため、このアプローチも正しくありません。
正しい解決策:
割り当てられたメモリを解放する正しい方法は次のとおりです:
buf->~Buffer();
::operator delete(mem);
このソリューションは、Buffer オブジェクトのデストラクター (buf->~Buffer()) を明示的に呼び出し、その後、operator delete 関数 (::operator delete() を使用して生のメモリの割り当てを解除します。 mem)).
ここでの重要な違いは、placement new を使用する場合、演算子の削除関数を直接呼び出して raw メモリを解放する必要があることです。配置 new 演算子から取得したポインターを削除しようとすると、デストラクターが適切に呼び出されないか、メモリ全体の割り当てが解除されません。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3