メインコンテンツ

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

sizeof を誤って使用している可能性があります

sizeof 演算子の使用が想定外の結果の原因となり得る

説明

この欠陥は、Polyspace® Bug Finder™sizeof 演算子の使用によるおそらくは想定外の結果を検出した場合に発生します。次に例を示します。

  • 配列のサイズを求めるため、sizeof 演算子が配列パラメーター名で使用されている。しかし、配列パラメーター名それ自体がポインターである。sizeof 演算子からは、そのポインターのサイズが返される。

  • 配列のサイズを求めるため、sizeof 演算子が配列要素で使用されている。しかし、演算子はその配列要素のサイズを返す。

  • 正しくない想定のもとに sizeof 演算子を先に使用したため、特定の関数 (strncmpwcsncpy など) の size 引数が不適切になっている。次に例を示します。

    • 関数呼び出し strncmp(string1, string2, num) で、num が、ポインターでの sizeof 演算子の誤使用により取得されている。

    • 関数呼び出し wcsncpy(destination, source, num) で、num がワイド文字の数ではなく、sizeof 演算子を使用して取得されたバイト単位のサイズとなっている。たとえば、wcsncpy(destination, source, (sizeof(desintation)/sizeof(wchar_t)) - 1) ではなく wcsncpy(destination, source, sizeof(destination) - 1) を使用した場合などです。

リスク

sizeof 演算子の不適切な使用は、次の問題の原因となることがあります。

  • sizeof 演算子により配列サイズが返され、その戻り値がループの制限に使用されることを想定している場合に、ループの実行回数が想定より少なくなる。

  • sizeof 演算子の戻り値がバッファーの割り当てに使用される場合に、バッファー サイズが必要なサイズより小さくなる。バッファーが不十分だと、結果としてバッファー オーバーフローなどの脆弱性などにつながることがあります。

  • sizeof 演算子の戻り値が関数呼び出しで不適切に使用される場合に、関数が想定どおりに動作しない。

修正方法

考えられる修正方法は次のとおりです。

  • sizeof 演算子を、配列サイズを決定するために配列パラメーター名や配列要素で使用しない。

    ベスト プラクティスは、配列サイズを別の関数パラメーターとして渡し、そのパラメーターを関数本体で使用することです。

  • sizeof 演算子を慎重に使用して、strncmpwcsncpy のような関数の数値引数を決定する。たとえば、wcsncpy などのワイド文字列関数で、バイト数ではなくワイド文字の数を引数として使用します。

すべて展開する

#define MAX_SIZE 1024

void func(int a[MAX_SIZE]) {
    int i;

    for (i = 0; i < sizeof(a)/sizeof(int); i++)    {
        a[i] = i + 1;
    }
}

この例では、sizeof(a) は配列サイズではなくポインター a のサイズを返します。

修正 — 配列サイズを別の方法で決定

1 つの修正方法として、別の方法を使用して配列サイズを決定します

#define MAX_SIZE 1024

void func(int a[MAX_SIZE]) {
    int i;

    for (i = 0; i < MAX_SIZE; i++)    {
        a[i] = i + 1;
    }
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: SIZEOF_MISUSE
影響度: High

バージョン履歴

R2015b で導入