メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C: Rule EXP33-C

Do not read uninitialized memory

説明

ルール定義

初期化されていないメモリを読み取らないようにします。1

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

  • 未初期化ポインター

  • 未初期化変数

チェッカーの拡張

チェッカーは次の方法で拡張できます。

すべて展開する

問題

未初期化ポインターは、デリファレンスの前にポインターにアドレスが割り当てられていない場合に発生します。

リスク

ポインターにアドレスが明示的に割り当てられていない場合、そのポインターは予測できない位置を指します。

修正方法

修正方法は欠陥の根本原因によって異なります。たとえば、アドレスをポインターに割り当てたが、その割り当てに到達不能である場合があります。

多くの場合、結果の詳細には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して逆のトレースを行い、これまでの関連するイベントを確認できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈も参照してください。

以下の修正例を参照してください。ポインターを宣言するときはポインターを NULL に初期化することをお勧めします。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

例 - 未初期化ポインター エラー
#include <stdlib.h>

int* assign_pointer(int* prev)
{
    int j = 42;
    int* pi;

    if (prev == NULL) 
      {
        pi = (int*)malloc(sizeof(int));
        if (pi == NULL) return NULL;
      }

    *pi = j;                     //Noncompliant
    /* Defect: Writing to uninitialized pointer */

    return pi;
}

prevNULL でない場合、ポインター pi にはアドレスが割り当てられません。しかし、prevNULL かどうかにかかわりなく、pi はすべての実行パスでデリファレンスされます。

修正 — すべての実行パスでポインターを初期化

1 つの修正方法として、prevNULL でない場合に pi にアドレスを割り当てることができます。

#include <stdlib.h>

int* assign_pointer(int* prev)
{
    int j = 42;
    int* pi;

    if (prev == NULL) 
       {
        pi = (int*)malloc(sizeof(int));
        if (pi == NULL) return NULL;
       } 
    /* Fix: Initialize pi in branches of if statement  */
    else 
        pi = prev;              
    

    *pi = j;

    return pi;
}
問題

未初期化変数は、変数の値が読み取られる前にその変数が初期化されていない場合に発生します。

リスク

変数が明示的に初期化されていない場合、変数値は予測できません。変数が特定の値をもつことは期待できません。

修正方法

修正方法は欠陥の根本原因によって異なります。たとえば、値を変数に割り当てたがその割り当てに到達不能であるか、条件付きステートメントの 2 つの分岐のいずれかで値を変数に割り当てた可能性があります。到達不能コードまたは割り当ての欠落を修正します。

多くの場合、結果の詳細には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して逆のトレースを行い、これまでの関連するイベントを確認できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈も参照してください。

以下の修正例を参照してください。宣言時に変数を初期化することをお勧めします。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

例 - 未初期化変数エラー
int get_sensor_value(void)
{
    extern int getsensor(void);
    int command;
    int val;

    command = getsensor();
    if (command == 2) 
      {
        val = getsensor();
      }

    return val;               //Noncompliant
    /* Defect: val does not have a value if command is not 2 */
}

command が 2 でない場合、変数 val には値が割り当てられません。この場合、関数 get_sensor_value の戻り値は未定です。

修正 — 宣言に際しての初期化

1 つの修正方法として、一部の実行パスで初期化が回避されることのないように、宣言時に val の初期化を行います。

int get_sensor_value(void)
{
    extern int getsensor(void);
    int command;
    /* Fix: Initialize val */
    int val=0;

    command = getsensor();
    if (command == 2) 
      {
        val = getsensor();
      }

    return val;              
 }

val には初期値 0 が割り当てられます。command が 2 と等しくない場合、関数 get_sensor_value はこの値を返します。

チェック情報

グループ: 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.