CWE Rule 843
説明
ルールの説明
The program allocates or initializes a resource such as a pointer, object, or variable using one type, but it later accesses that resource using a type that is incompatible with the original type.
Polyspace 実装
ルール チェッカーは以下の問題をチェックします。
異なる型のオブジェクトを指すポインターへのキャスト
最初に再初期化せずに、再割り当てされたメモリを別の型のオブジェクトから読み取る
例
この問題は、あるオブジェクト型へのポインターと別のオブジェクト型へのポインターの間でキャストを実行する場合に発生します。
オブジェクトへのポインターが別のオブジェクトへのポインターにキャストされる場合、結果のポインターは正しく配置されない可能性があります。不適切なアライメントは未定義の動作を発生させます。
変換によって正しく配置されたポインターが生成されたとしても、そのポインターがオブジェクトへのアクセスに使用される場合、動作が未定義となることがあります。
例外:オブジェクト型を指すポインターは、以下のいずれかの型を指すポインターに変換できます。
charsigned charunsigned char
signed char *p1;
unsigned int *p2;
void foo(void){
p2 = ( unsigned int * ) p1; /* Non-compliant */
}この例では、p1 は signed char オブジェクトを指します。しかしながら、p1 は範囲のより広いオブジェクト型 unsigned int を指すポインターにキャストされています。
extern unsigned int read_value ( void );
extern void display ( unsigned int n );
void foo ( void ){
unsigned int u = read_value ( );
unsigned short *hi_p = ( unsigned short * ) &u; /* Non-compliant */
*hi_p = 0;
display ( u );
}この例では、u は unsigned int 変数です。&u は、範囲のより狭いオブジェクト型 unsigned short を指すポインターにキャストされています。
ビッグエンディアン マシンでは、ステートメント *hi_p = 0 は &u が指すメモリ位置の高位ビットをクリアしようと試みます。しかし、display(u) の結果を見ると、その高位ビットがクリアされていないことがあります。
const short *p;
const volatile short *q;
void foo (void){
q = ( const volatile short * ) p; /* Compliant */
}この例では、p と q のいずれも short オブジェクトを指します。この両者間のキャストは volatile 修飾子のみを追加し、したがって準拠性をもちます。
この問題は、以下の操作を順に実行すると発生します。
元の割り当てとは異なる型のオブジェクトにメモリを再割り当てする。
たとえばこのコードの抜粋では、本来
struct A*型のポインターに割り当てられていたメモリが、struct B*型のポインターに再割り当てされます。struct A; struct B; struct A *Aptr = (struct A*) malloc(sizeof(struct A)); struct B *Bptr = (struct B*) realloc(Aptr, sizeof(struct B));再割り当てされたメモリを最初に再初期化せずに、このメモリから読み取る。
再割り当てされたメモリを指すポインターでの読み取りアクセスは、ポインター デリファレンスまたは配列のインデックス付けにおいて発生する可能性があります。
const修飾子付きオブジェクトへのポインターを受け取る関数に、対応するパラメーターとしてこのポインターを渡す操作も、読み取りアクセスとしてカウントされます。
再初期化されていない再割り当てメモリからの読み取りを行うと、未定義の動作につながります。
再割り当ての後、最初の読み取りアクセスの前にメモリを再初期化します。
チェッカーでは、再割り当てされたメモリを指すポインターでの書き込みアクセスすべてが (オブジェクトの再初期化が部分的である場合でも)、再初期化の要件を満たしているものと解釈されます。再割り当てされたメモリを指すポインターでの書き込みアクセスは、ポインター デリファレンスと配列のインデックス付けにおいて発生する可能性があります。const 修飾子付きでないオブジェクトへのポインターを受け取る関数に、対応するパラメーターとしてこのポインターを渡す操作も、書き込みアクセスとしてカウントされます。
#include<stdlib.h>
struct group {
char *groupFirst;
int groupSize;
};
struct groupWithID {
int groupID;
char *groupFirst;
int groupSize;
};
char* readName();
int readSize();
void createGroup(int nextAvailableID) {
struct group *aGroup;
struct groupWithID *aGroupWithID;
aGroup = (struct group*) malloc(sizeof(struct group));
if(!aGroup) {
/*Handle error*/
}
aGroup->groupFirst = readName();
aGroup->groupSize = readSize();
/* Reassign to group with ID */
aGroupWithID = (struct groupWithID*) realloc(aGroup, sizeof(struct groupWithID));
if(!aGroupWithID) {
free(aGroup);
/*Handle error*/
}
if(aGroupWithID -> groupSize > 0) { /* Noncompliant */
/* ... */
}
/* ...*/
free(aGroupWithID);
}
この例では、関数 malloc を使用して group* ポインターに割り当てられたメモリを、関数 realloc を使用して、groupWithID* ポインターに再割り当てします。再割り当てされたメモリを再初期化する前に、このメモリへの読み取りアクセスが行われます。
最初の読み取りアクセスの前に、groupWithID* ポインターに割り当てられているメモリを再初期化します。メモリのすべてのビットは、関数 memset を使用して再初期化できます。
#include<stdlib.h>
#include<string.h>
struct group {
char *groupFirst;
int groupSize;
};
struct groupWithID {
int groupID;
char *groupFirst;
int groupSize;
};
char* readName();
int readSize();
void createGroup(int nextAvailableID) {
struct group *aGroup;
struct groupWithID *aGroupWithID;
aGroup = (struct group*) malloc(sizeof(struct group));
if(!aGroup) {
/*Handle error*/
}
aGroup->groupFirst = readName();
aGroup->groupSize = readSize();
/* Reassign to group with ID */
aGroupWithID = (struct groupWithID*) realloc(aGroup, sizeof(struct groupWithID));
if(!aGroupWithID) {
free(aGroup);
/*Handle error*/
}
memset(aGroupWithID, 0 , sizeof(struct groupWithID));
/* Reinitialize group */
if(aGroupWithID -> groupSize > 0) {
/* ... */
}
/* ...*/
free(aGroupWithID);
}
チェック情報
| カテゴリ: Type Errors |
バージョン履歴
R2023a で導入修飾子がないオブジェクト型へのポインターを次のいずれかの型のポインターに変換する場合、Polyspace® は違反を報告しません。
charsigned charunsigned char
修飾子付きオブジェクトのポインターを変換する場合は、変換後の型が char*、signed char*、unsigned char* のいずれかである場合でも、Polyspace が違反を報告します。
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)