0

私は常に次のようmallocに返されるものをチェックしてきました:

void *p; 
p = malloc(100);
if (p) 
{ 
  perror("malloc"); 
  return false;
}

しかし、メモリを確実に取得できるのに、なぜそれを行うのでしょうか?

#define GET_MEM(p,s,i) do{for(p=NULL,i=0;!(p=calloc(1,s))&&i<5;perror("calloc"),i++)}while(0)

prosそのconsような決定の根拠は何ですか?それはどのように行われるべきですか?

4

2 に答える 2

2

メモリの取得を保証できるのであれば、なぜそれを行うのですか。

あなたの仮定は間違っています。

malloc() calloc()し、realloc()失敗する可能性があります。したがって、要求されたメモリが正常に割り当てられない場合、これらの関数は NULL を再実行します。このチェックが存在しない場合は、未定義の動作を引き起こす、割り当てられていないこのメモリ ロケーションへの書き込みを開始します。

マクロに do while ループがある理由について質問がある場合。以下のリンクはそれを本当によく説明しています

do { ... } while (0) — 何の役に立つの?

于 2015-01-21T09:06:08.863 に答える
1

まず第一に、これは正しくなく、実際には本来あるべきこととは逆のことを行います:

void *p; 
p = malloc(100);
if (p) 
{ 
  perror("malloc"); 
  return false;
}

この if ステートメントは次のように述べています。if( malloc succeeded ){ return AN_ERROR; }

それは言うべきです:

void *p; 
p = malloc(100);
if( NULL == p ) 
{ 
  perror("malloc"); 
  return false;
}

さて、あなたの質問について:

しかし、メモリを確実に取得できるのに、なぜそれを行うのでしょうか?

Gopi が述べたように、メモリの取得を保証することはできません。メモリが不足する可能性が非常に高く、これ以上割り当てることができなくなります。プロセスで使用可能なメモリをすべて使い果たすことはほとんどありませんが、発生する可能性があります。malloc()これが、 、calloc()、 などの関数の戻り値をチェックすることrealloc()が不可欠である理由です。

これらのメモリ割り当て関数は、十分なメモリがない場合に失敗する可能性があり、それを処理する準備ができている必要があります。文字列にスペースを割り当てたが、malloc が失敗し、それをチェックしなかったとします。

int main(int argc, char *argv[]){
    char stringToCopy[] = "Some very long string would be here ...";
    char *stringBuffer = malloc( 1000 ); // 1000 char buffer
    // Malloc failed and we did not check for it
    strncpy(stringBuffer, stringToCopy); /* UNDEFINED BEHAVIOUR */
    return 0;
}

したがって、この状況では malloc が失敗し、とにかく文字列をバッファにコピーしようとしました。これを開始するとすぐに、未定義の動作が発生します。通常、この種のアクションは、セグメンテーション フォールトが原因でプログラムがクラッシュする原因となります。

これは深刻な事態になる可能性があり、データの損失やサービスの損失につながる可能性があります。少なくとも、セグメンテーション違反はユーザーに不便をもたらします。

いくつかの一般的な規則として: 、および;の戻り値を常に確認してください。これらの関数が成功したと盲目的に信じてはいけません。malloc()calloc()realloc()

マクロ内でこのチェックを行うかどうかは、あなた自身の選択です (多くの長所/短所はありません) が、チェックを実行し、適切に実行するようにしてください。

于 2015-01-21T09:43:57.317 に答える