『高品質C++/Cプログラミングガイド』のメモリが尽きたらどうする?


ダイナミックメモリを申請するときに十分なメモリブロックが見つからない場合、mallocとnewはNULLポインタを返し、メモリ申請に失敗したことを宣言します.通常、メモリ消費量の問題は3つの方法で処理されます.
(1)ポインタがNULLであるか否かを判断し,そうであれば直ちにreturn文で本関数を終了する.例:
void Func(void)
{
    A  *a = new A;

    if(a == NULL)
   {
       return;
   }
   …
}

(2)ポインタがNULLであるか否かを判断し,もしそうであれば直ちにexit(1)でプログラム全体の実行を終了する.例:
 
void Func(void)
{
    A  *a = new A;
    if(a == NULL)
   {
       cout << “Memory Exhausted” << endl;
       exit(1);
    }
    …
}

 
(3)newとmallocに異常処理関数を設定する.例えばVisual C++が使えますset_new_hander関数はnewにユーザ自身が定義した異常処理関数を設定し,mallocにnewと同じ異常処理関数を享受させることもできる.詳細はC++マニュアルを参照してください.
 
上記(1)(2)の方式が最も一般的に用いられる.1つの関数内にダイナミックメモリを申請する必要がある箇所が複数ある場合、方式(1)は力不足(メモリを解放するのが面倒)に見え、方式(2)で処理すべきである.
 
多くの人がexit(1)を使うのに忍びず、「エラーハンドラを書かずに、オペレーティングシステムに自分で解決させてはいけませんか?」と聞く.
 
だめです.「メモリが切れた」ということが起こった場合、一般的にはアプリケーションには救いようがない.exit(1)で悪いプログラムを殺さなければ、オペレーティングシステムを殺す可能性があります.悪党を射殺しなければ、悪党は老いて死ぬ前にもっと多くの罪を犯すことになる.
 
皆さんに伝えたい重要な現象があります.32ビット以上のアプリケーションでは、mallocとnewをどのように使用しても「メモリ消費」を招くことはほとんどありません.例7-9を参照して、Windows 98の下でVisual C++でテストプログラムを作成しました.このプログラムは絶え間なく実行され、終了することはありません.32ビットオペレーティングシステムが「ダミーメモリ」をサポートしているため、メモリが切れ、自動的にハードディスク(HDD)領域で置き換えられます.ハードディスク(HDD)がガチャガチャと音を立てているだけで、Window 98はキーボードやマウスに反応しないほど疲れています.
 
32ビット以上のアプリケーションでは、「メモリ消費量」エラーハンドラは役に立たないという結論に達しました.これでUnixとWindowsのプログラマーたちを楽しませてしまいました.どうせエラー処理プログラムが役に立たないので、私は書かないで、多くの面倒を省きました.
 
私は読者を誤導したくない.誤った処理をしないとプログラムの品質が悪くなり、決して小さなミスで大きくしてはいけないと強調しなければならない.
 
void main(void)
{
    float *p = NULL;
    while(TRUE)
    {
        p = new float[1000000]; 
        cout << “eat memory” << endl;
        if(p==NULL)
            exit(1);
    }
}