web-dev-qa-db-ja.com

カーネルがオーバーコミットメモリを使用する場合、メモリを割り当てた後にNULLをチェックする必要がありますか?

Malloc()の後にNULL(メモリが正常に割り当てられているかどうか)をチェックするのが一般的な方法です。

void *ptr = malloc(10);    
if (ptr != NULL) {  
  // do some thing usefull  
} else {  
 // no memory. safely return/throw ...  
}  

カーネルでメモリオーバーコミットが有効になっている場合、NULLになる可能性はありますか?割り当てごとにNULLを宗教的にチェックする慣行に従う必要がありますか?積極的なオーバーコミットメカニズムにもかかわらず、mallocはNULLを返しますか(値1だと思います)?

実際のところ、Androidカーネルはメモリのオーバーコミットを使用しています(値がわからないので、値(オーバーコミット値)とその重要性を知りたいです)。フレームワークソースの一部(C/C++) Android(サードパーティの可能性があります)のコードは、NULLをチェックせず、割り当て後にbad_allocをキャッチしません。何かが足りませんか?

SOにはオーバーコミットメモリに関するスレッドがいくつかありますが、どれも私の混乱を解決しませんでした。

編集: 積極的なオーバーコミットが採用されている場合、NULLは返されません(仮定1)。使用可能な物理メモリがなく、割り当てられたメモリにアクセスしようとすると(割り当てられたメモリに書き込む)、OOMはプロセスを強制終了し、アプリケーションが強制終了されるまでメモリを割り当てます(仮定2)。どちらの場合でも、NULLをチェックする必要はありません(メモリが割り当てられるか、プロセスが強制終了されます)。私は私の仮定に正しいですか?
移植性はこの質問の問題ではありません。

27
FL4SOF

はい、mallocによって返される失敗をチェックする必要があります。メモリをオーバーコミットする環境では、前回のmallocの呼び出しによってプログラムに割り当てられたアドレス空間の一部に書き込むときに必要な物理ストレージが不足しているため、障害を検出して回復することはできません。

ただし、従来の環境でmallocが失敗する原因となる問題はこれだけではありません。プログラムのアドレス空間が断片化されたときに特に大きなメモリブロックを要求すると、要求を満たすのに十分な合計物理メモリが存在する可能性がある場合でも、失敗する可能性があります。空きアドレス空間の連続した範囲がないため、mallocは失敗する必要があります。このタイプの障害は、環境がメモリをオーバーコミットしているかどうかに関係なく、mallocNULLを返すことによって通知される必要があります。

38
CB Bailey

NULLの戻り値を確認する必要があります時間。すべてのライブラリ関数が失敗する可能性があります。 fclose()でも実行します(切断されたNFS共有で、NFSファイルのfcloseからのエラーは、データが保存されなかったことを意味します)。

ほとんどのソフトウェアはひどく書かれていて、すべてのチェックが含まれているわけではありません。

mallocは、NULLまたはポインター以外のものを返すことはできません。全部かゼロか。 10を要求した場合、mallocから1バイトを取得することはできません。

8
osgx

カーネルにオーバーコミット可能なメモリがあるかどうかに関係なく、NULLを返す可能性のあるすべての関数呼び出しでNULLを厳密にチェックすることをお勧めします。

以下の次のコードセグメントは、mallocへの呼び出しが機能したかどうかを確認する方法を示しています...

 void * ptr = malloc(10); 
 if(ptr!= NULL){
/* ptrを使用してここで何かを行う*/
} else {
/*失敗した場合はここで何かを実行します*/
} 

ファイル操作、名前を付けるメモリ操作ですが、失敗するとNULLを返すものもあります。

これがお役に立てば幸いです、よろしく、トム。

2
t0mm13b

linuxでは、メモリは(最初は)ページバッキングされておらず、最初の読み取り/書き込み後にのみページバッキングを作成するため、OSは常にメモリを提供します(アドレス空間を使い果たした場合を除き、64ビットシステムでは不可能です)。 )。したがって、メモリが不足し、約束されたメモリを提供できない場合、OOM killerは、アプリケーションまたはその他のアプリケーションを強制終了して、必要なページバッキングを提供します。したがって、NULLチェックを実行するかどうかに関係なく、結果は同じで、クラッシュします.....。

1