メインコンテンツ

保護されていない動的メモリ割り当て

動的割り当てから返されるポインターに対して NULL または nullptr の値のチェックが行われない

説明

この欠陥は、前回のメモリ割り当てが成功したかどうかを初めにチェックせずに動的に割り当てられたメモリにアクセスしたときに発生します。

リスク

malloccalloc または realloc を使用してメモリを動的に割り当てる際、要求されたメモリが使用可能でない場合は値 NULL が返されます。割り当ての後、コードでこの NULL 値をチェックせずにメモリ ブロックにアクセスした場合、このアクセスの成功は保証されません。

修正方法

割り当てられたメモリ位置にアクセスする前に、malloccalloc、または realloc の戻り値が NULL かどうかをチェックします。

int *ptr = malloc(size * sizeof(int));

if(ptr) /* Check for NULL */ 
{
   /* Memory access through ptr */
}

すべて展開する

#include <stdlib.h>

void Assign_Value(void) 
{
  int* p = (int*)calloc(5, sizeof(int));

  *p = 2;  
  /* Defect: p is not checked for NULL value */

  free(p);
}

メモリ割り当てが失敗した場合、関数 callocNULLp に返します。p を使用してメモリにアクセスする前に、コードでは pNULL かどうかのチェックを行っていません。

修正 — null 値をチェック

1 つの修正方法として、デリファレンスの前に p の値が NULL かどうかをチェックすることができます。

#include <stdlib.h>

void Assign_Value(void)
 {
   int* p = (int*)calloc(5, sizeof(int));

   /* Fix: Check if p is NULL */
   if(p!=NULL) *p = 2; 

   free(p);
 }
#include <stdlib.h>
#include<string.h>
typedef struct recordType {
    const char* id;
    const char* data;
} RECORD;

RECORD* MakerecordType(const char *id,unsigned int size){
    RECORD *rec = (RECORD *)calloc(1, sizeof(RECORD));
    rec->id = strdup(id);

    const char *newData = (char *)calloc(1, size);
    rec->data = newData;
    return rec;
}

この例では、前回の動的メモリ割り当てからの NULL 値をチェックせずにポインター rec がデリファレンスされたときに、チェッカーが欠陥を報告します。

同様の問題がポインター newData でも発生します。ただし、ポインターはデリファレンスされませんが、rec->data にコピーされるだけなので、欠陥は報告されません。null の可能性があるポインターにコピーするだけでは問題になりません。たとえば、関数 recordType_new の呼び出し元がデリファレンスの前に rec->dataNULL 値をチェックすれば、null ポインターのデリファレンスは回避されます。

結果情報

グループ: 動的メモリ
言語: C | C++
既定値: オフ
コマンド ライン構文: UNPROTECTED_MEMORY_ALLOCATION
影響度: Low

バージョン履歴

R2013b で導入