0

新しい関数をオーバーロードしましたが、残念ながら、コンパイラでより多くのメモリ アクセスを要求するグローバル ハンドラを実行できませんでした。また、以下のコード スニペットのように、より多くのメモリを要求するためにグローバル ハンドラーを呼び出すと、P への割り当てがどのように行われるかわかりません。

誰かがこれについて何らかの光を当てることができれば幸いです

void * Pool:: operator new ( size_t size ) throw( const char *)
{
    int n=0;
    while(1)
    {
        void *p = malloc (100000000L);
        if(p==0)
        {
            new_handler ghd= set_new_handler(0);//deinstall curent handler
            set_new_handler(ghd);// install global handler for more memory access
            if(ghd)
                (*ghd)();
            else 
                throw "out of memory exception";
        }
        else
        {
            return p;
        }
    }
}
4

2 に答える 2

0

効果を得るには、プログラムの他の部分が以前にグローバルハンドラーをインストールしている必要があります。そのハンドラーには、ハンドラーが呼び出されたときに解放するための何らかのメモリも必要です(おそらく、破棄できるいくつかのバッファーまたはキャッシュ)。

デフォルトのnew_handlerは単なるnullポインターであるため、コードが例外をスローする可能性が非常に高くなります。

bad_allocまた、他のオーバーロードと一貫性を保つために例外をスローしましたoperator new

于 2013-03-04T09:40:01.740 に答える
0

ここで議論すべきことが 2 つあります。1 つ目はnew_handlerの使用、2 つ目は演算子 newのオーバーロードです。

set_new_handler()

new_handlerを使用する場合は、登録する必要があります。これは通常、main()に入った後に最初に行うことです。ハンドラーも提供する必要があります。

#include <iostream>
#include <new>

void noMemory() throw()
{
  std::cout << "no memory" << std::endl;
  exit(-1);
}

int main()
{
  set_new_handler(noMemory);
  // this will probably fail and noMemory() will be called
  char *c = new char[100000000L];
  std::cout << "end" << std::endl;
}

メモリを割り当てられない場合は、登録済みのハンドラーが呼び出され、メモリを解放する機会があります。ハンドラーが戻ると、オペレーター newは、要求された量のメモリーの割り当てをもう一度試みます。

オペレーター新規

デフォルトの演算子 newの構造は、あなたが提示したものと似ています。new_handlerの観点から、重要な部分はwhile(1)ループです。これは、 new_handlerが呼び出された後にメモリを取得しようとする責任があるためです。

このwhile(1)ループから抜け出す方法は 2 つあります。

  • 有効なポインタを取得する
  • 例外を投げる

new_handlerを提供するときは、これを念頭に置く必要があります。メモリを解放するために何もできない場合は、ハンドラーをアンインストールする (または終了するか、例外をスローする) 必要があります。そうしないと、無限ループに陥る可能性があります。

コードでパラメーター サイズを省略するのは、テスト目的のためだけだと思います。

詳細については、Scott Meyers の「Effective C++ Item 7」も参照してください。演算子 new はパラメーター size = 0 の場合でも有効なポインターを返す必要があるため、ユーザーが 0 のバイト数を割り当てたい場合、演算子 newで最初に行うことは size を 1 に上書きする必要があります。このトリックはシンプルでかなり効果的です。

于 2013-03-04T11:20:06.543 に答える