7
#include <new>
#include <cstdlib>
#include <iostream>
#include <stdexcept>

struct foo {};

inline void* operator new(size_t size, foo*) throw (std::bad_alloc)
{
    std::cout << "my new " << size << std::endl;
    return malloc(size);
}

inline void operator delete(void* p, foo*) throw()
{
    std::cout << "my delete" << std::endl;
    free(p);
}

int main()
{
    delete new((foo*)NULL) foo;
}

出力 ( ideone 経由):

my new 1

私の考えでは、C++ は追加の引数で new されたオブジェクトを解放し、一致する同じ引数を削除すると考えていましたが、明らかに間違っていました。

オーバーロードされた削除を呼び出すために上記のコードを取得する正しい方法は何ですか?

4

1 に答える 1

8

バージョンを除いて、新しい配置の形式を使用する場合はstd::nothrow_t、オブジェクトを明示的に破棄し、適切と思われる方法でそのメモリを解放する必要があります。ただし、オブジェクトの構築で例外がスローされた場合に使用されるため、オーバーロードされたバージョンoperator delete()は引き続き存在する必要があります。この場合、例外がスローされるため、ポインタは返されません。したがって、メモリを取り除くことは、この割り当てプロセスで実行する必要があります。

つまり、次main()のようになります。

int main()
{
    foo* p = new (static_cast<foo*>(0)) foo;
    p->~foo();
    operator delete(p, static_cast<foo*>(0));
}
于 2012-11-21T23:52:48.450 に答える