4

次の宣言があります。

void * operator new (size_t s, PersistentMemory * m) throw()
   {return m->allocatePersistentMemory(s);}

起動時にメモリの枯渇をテストしています。その結果、m->allocatePersistentMemory(s);0 が返されます。次に、New は、null ポインターを使用してコンストラクターを呼び出します。this

ただし、C++ 2003 標準の 3.7.3.1 パラグラフ 3 に基づくと、次のようになります。

ストレージの割り当てに失敗した割り当て関数は、現在インストールされている new_handler (18.4.2.2) があればそれを呼び出すことができます。[注: プログラムが提供する割り当て関数は、set_new_handler 関数 (18.4.2.3) を使用して、現在インストールされている new_handler のアドレスを取得できます。] 空の例外仕様 (15.4) で宣言された割り当て関数 throw() がストレージの割り当てに失敗した場合、null ポインターを返す必要があります。ストレージの割り当てに失敗したその他の割り当て関数は、クラス std::bad_alloc (18.4.2.1) または std::bad_alloc から派生したクラスの例外をスローすることによってのみ、失敗を示します。

私が物事を理解する方法は、null を返すと、コンストラクターを呼び出さずm->allocatePersistentMemory(s)に全体が null を返すことになるということです。operator new() throw()これをオーバーライドする他の条件が他にありませんか?

ありがとう!

4

2 に答える 2

2

C++03 標準のセクション 5.3.4 (13) には、次のように記載されています。

[: 割り当て関数が空の 例外仕様(15.4) で宣言されていない限り、 bad_allocthrow()例外をスローしてストレージの割り当てに失敗したことを示します (第 15 節、18.4.2.1)。それ以外の場合は、null 以外のポインターを返します。割り当て関数が空の例外仕様で宣言されている場合、ストレージの割り当てに失敗したことを示すために null を返し、それ以外の場合は null 以外のポインターを返します。] 割り当て関数が null を返す場合、初期化は行われず、割り当て解除関数は呼び出されず、new-expressionの値はnull になります。throw()

「初期化を行わない」というフレーズは、コンストラクターが呼び出されないことを意味します。

興味深いことに、仕様を間違って読んでいない限り、割り当て関数throw()が null を指定して返す場合、「new」自体の呼び出しの値は null です。私はいつもこれは不可能だと思っていました (たとえば、Will new return NULL in any case? のほとんどすべての回答を参照してください)。

于 2012-07-17T00:32:09.503 に答える
2

あなたが電話しているnewと思っているのに電話していないのではないかと思います。

これは期待どおりに機能します。

void *myalloc (size_t) { return 0; }
void * operator new (size_t s) throw() { return myalloc(s); }
struct Foo {
    std::string s;
    Foo () { std::cout << this << std::endl; }
};
int main () {
    Foo *f = new Foo;
    if (f == 0) std::cout << "f is NULL" << std::endl;
}

ただし、これは失敗します。

void *myalloc (size_t) { return 0; }
void * operator new (size_t s) throw() { return myalloc(s); }
struct Foo {
    std::string s;
    Foo () { std::cout << this << std::endl; }
    void * operator new (size_t s) { return myalloc(s); }
};
int main () {
    Foo *f = new Foo;
    if (f == 0) std::cout << "f is NULL" << std::endl;
}
于 2012-07-17T00:43:35.980 に答える