メインコンテンツ

CERT C: Rule EXP34-C

Do not dereference null pointers

説明

ルール定義

NULL ポインターをデリファレンスしないようにします。1

Polyspace 実装

ルール チェッカーは、"NULL ポインター" をチェックします。

チェッカーの拡張

入力値が不明であり、入力のサブセットのみがエラーの原因として考えられる場合、既定の Bug Finder 解析ではこのルールに対する違反が報告されない場合があります。特定のシステム入力値を原因とする違反の有無をチェックするには、より厳密な Bug Finder 解析を実行してください。特定のシステム入力値から欠陥を見つけるための Bug Finder チェッカーの拡張を参照してください。

すべて展開する

問題

NULL ポインターは、NULL 値のポインターを有効なメモリ位置を指しているかのように使用する場合に発生します。

リスク

NULL ポインターのデリファレンスは未定義の動作です。ほとんどの実装では、このデリファレンスによってプログラムがクラッシュする可能性があります。

修正方法

デリファレンスの前にポインターが NULL かどうかをチェックします。

以前に NULL かどうかをチェックしていたにもかかわらず、この問題が発生する場合は、このチェックと以降のデリファレンスの間で中間イベントを探します。多くの場合、結果の詳細 (または Polyspace as You Code のソース コード ツールヒント) には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して、欠陥に関連する変数のこれまでの参照を検索し、関連するイベントを検出できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈またはPolyspace Access Web インターフェイスでの Bug Finder の結果の解釈 (Polyspace Access)も参照してください。

以下の修正例を参照してください。

例 - NULL ポインター エラー
#include <stdlib.h>

int FindMax(int *arr, int Size) 
{
 int* p=NULL;

 *p=arr[0]; //Noncompliant
 /* Defect: Null pointer dereference */

 for(int i=0;i<Size;i++)
  {
   if(arr[i] > (*p))
     *p=arr[i];    
  }

 return *p;
}

ポインター pNULL の値で初期化されます。しかし、値 arr[0]*p に書き込まれるとき、p は有効なメモリ位置を指していると想定されます。

修正 — デリファレンスの前に null ポインターにアドレスを割り当てる

1 つの修正方法として、デリファレンスの前に有効なメモリ アドレスで p を初期化することができます。

#include <stdlib.h>

int FindMax(int *arr, int Size) 
{
 /* Fix: Assign address to null pointer */
 int* p=&arr[0];       

 for(int i=0;i<Size;i++)
  {
   if(arr[i] > (*p))
     *p=arr[i];    
  }

 return *p;
}

チェック情報

グループ: Rule 03.式 (EXP)

バージョン履歴

R2019a で導入

すべて展開する


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.