メインコンテンツ

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

ポインターと整数間での変換は安全ではありません

ポインターと整数型間の変換によるミスアライメントまたは不適切な結果

説明

この欠陥は、intptr_tuintprt_t などのポインター型と、enumptrdiff_tpid_t などの整数型の間で変換が行われた場合に発生します。

リスク

ポインターと整数とのマッピングは、環境のアドレス指定構造と必ずしも一致するとは限りません。

ポインターから整数への変換により、以下が生じる可能性があります。

  • 整数値の切り捨てまたは範囲外の整数値。

  • 不適切な整数型。

整数からポインターへの変換により、以下が生じる可能性があります。

  • ポインターまたはオブジェクトのミスアライメント。

  • 不適切なポインター アドレス。

修正方法

可能であれば、ポインターから整数への変換または整数からポインターへの変換を避けます。void ポインターを整数に変換する場合は、値が変化しないように、以下の型を使用します。

  • C99 — intptr_t または uintptr_t

  • C90 — size_t または ssize_t

すべて展開する

 unsigned int *badintptrcast(void)
{
    unsigned int *ptr0 = (unsigned int *)0xdeadbeef;
    char *ptr1 = (char *)0xdeadbeef;
    unsigned int *explicit_ptr = reinterpret_cast<unsigned int*>(0xdeadbeef);
    return (unsigned int *)(ptr0 - (unsigned int *)ptr1);
}

この例には、安全でない変換 3 つと安全な変換 1 つ、合わせて 4 つの変換があります。

  • 0xdeadbeef から unsigned int* への変換により、ポインターにアライメントの問題が発生します。Polyspace® はこの変換にフラグを設定します。

  • 0xdeadbeef から char * への変換では char のアライメントの問題は発生しないため、この変換にはフラグは設定されません。

  • 0xdeadbeef から unsigned int* への明示的な reinterpret_cast により、ポインターにアライメントの問題が発生します。Polyspace はこの変換にフラグを設定します。

  • 戻り値での変換により、ptrdiff_t がポインターにキャストされます。このポインターは、不適切なアドレスを指している可能性があります。Polyspace はこの変換にフラグを設定します。

修正 — intptr_t を使用

考えられる 1 つの修正方法として、intptr_t 型を使用してポインター アドレス 0xdeadbeef を格納します。また、ptrdiff_t からポインターへの変換がなくなるように、2 つ目のポインターを整数オフセットに変更できます。

#include <stdint.h>

unsigned int *badintptrcast(void)
{
    intptr_t iptr0 = (intptr_t)0xdeadbeef;
    int offset = 0;
    return (unsigned int *)(iptr0 - offset);
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: オフ
コマンド ライン構文: BAD_INT_PTR_CAST
影響度: Medium

バージョン履歴

R2016b で導入