メインコンテンツ

ISO/IEC TS 17961 [alignconv]

Converting pointer values to more strictly aligned pointer types

説明

ルール定義

アライメントがより厳密なポインター型へのポインター値の変換。1

Polyspace 実装

このチェッカーは、キャストに割り当てられた誤ったオブジェクト サイズをチェックします。

すべて展開する

問題

キャストに割り当てられた誤ったオブジェクト サイズはポインター変換時にポインターのアドレスが整列していない場合に生じます。ポインターを異なるポインター型に変換する際に、割り当てられたメモリのサイズは変換先のポインターのサイズの倍数でなければなりません。

リスク

整列していないポインターをデリファレンスすると、未定義の動作が発生し、プログラムがクラッシュする可能性があります。

修正方法

ポインター ptr1ptr2 に変換するとします。ptr1N バイトのバッファーを指し、ptr2type * ポインターで、sizeof(type)n バイトの場合、Nn の整数倍であることを確認します。

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

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

例 - ポインターの動的割り当て
#include <stdlib.h>

void dyn_non_align(void){
    void *ptr = malloc(13);
    long *dest;

    dest = (long*)ptr; //defect
}

この例では、ptr から long* への変換に関する欠陥が報告されます。ptr に動的に割り当てられるメモリである 13 バイトは、dest のサイズである 4 バイトの倍数ではありません。この不整列のため、キャストに割り当てられた誤ったオブジェクト サイズの欠陥が生じます。

修正 — ポインターのサイズを変更

1 つの修正方法として、変換先のサイズの倍数となるポインター サイズを使用することができます。この例では、割り当てられるメモリを 13 ではなく 12 に変更して欠陥を解決します。

#include <stdlib.h>

void dyn_non_align(void){
    void *ptr = malloc(12);
    long *dest;

    dest = (long*)ptr;
}
例 - ポインターの静的割り当て
void static_non_align(void){
    char arr[13], *ptr;
    int *dest;

    ptr = &arr[0];
    dest = (int*)ptr; //defect
}

この例では、行 6 で ptrint* に変換する際に欠陥が報告されます。配列 arr のサイズは 13 バイトであるため、ptr のメモリ サイズは 13 バイトです。dest のサイズは 4 バイトで、13 の倍数ではありません。この不整列のため、キャストに割り当てられた誤ったオブジェクト サイズの欠陥が生じます。

修正 — ポインターのサイズを変更

1 つの修正方法として、変換先のサイズの倍数となるポインター サイズを使用することができます。この例では、配列 arr のサイズを 4 の倍数に変更して欠陥を解決します。

void static_non_align(void){
    char arr[12], *ptr;
    int *dest;

    ptr = &arr[0];
    dest = (int*)ptr;
}
例 - 関数による割り当て
#include <stdlib.h>

void *my_alloc(int size) { 
    void *ptr_func = malloc(size); 
    if(ptr_func == NULL) exit(-1); 
    return ptr_func; 
}

void fun_non_align(void){
    int *dest1;
    char *dest2;

    dest1 = (int*)my_alloc(13);  //defect
    dest2 = (char*)my_alloc(13); //not a defect
}

この例では、行 11 において my_alloc(13) で返されるポインターを int* に変換する際に欠陥が生じます。my_alloc(13) は動的に割り当てられた 13 バイトのサイズのポインターを返します。dest1 のサイズは 4 バイトで、13 の除数ではありません。この不整列のため、キャストに割り当てられた誤ったオブジェクト サイズの欠陥が生じます。行 12 で、同じ関数呼び出し my_alloc(13) は、dest2 の変換に対し欠陥にはなりません。char* のサイズの 1 バイトが 13 の除数であるためです。

修正 — ポインターのサイズを変更

1 つの修正方法として、変換先のサイズの倍数となるポインター サイズを使用することができます。この例では、my_alloc の引数を 4 の倍数に変更して欠陥を解決します。

#include <stdlib.h>

void *my_alloc(int size) { 
    void *ptr_func = malloc(size); 
    if(ptr_func == NULL) exit(-1); 
    return ptr_func; 
}

void fun_non_align(void){
    int *dest1;
    char *dest2;

    dest1 = (int*)my_alloc(12); 
    dest2 = (char*)my_alloc(13); 
}

チェック情報

決定可能性:決定不可能

バージョン履歴

R2019a で導入


1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.