パディング データのメモリ比較
構造体のパディングで格納したデータを memcmp
で比較している
説明
この欠陥は、関数 memcmp
を使用して、2 つの構造体全体が比較された場合に発生します。この処理では、構造体のパディングで格納された無意味なデータが比較されます。
次に例を示します。
struct structType { char member1; int member2; . . }; structType var1; structType var2; . . if(memcmp(&var1,&var2,sizeof(var1))) {...}
リスク
構造体のメンバーが異なるデータ型を持っている場合、コンパイラはメモリ内のデータ アライメントのために追加のパディングを導入します。パディングの例については、ローカル変数サイズのより高い推定値
(Polyspace Code Prover)を参照してください。
これらの追加のパディング バイトの内容に意味はありません。C 標準では、さまざまなコンパイラが独自のパディングを自由に実装できるように、それらのバイトのコンテンツが不確定になることを許容しています。memcmp
で構造体のバイト単位の比較を実行する場合、パディングに格納された意味のないデータも比較されます。対応するメンバーが同じ値であっても、2 つのデータ構造体が等しくないという誤った結論になる可能性があります。
修正方法
2 つの構造体を 1 回の試行で比較するのではなく、構造体のメンバーごとに比較します。
効率的なコードにするには、メンバーごとに比較を行う関数を作成します。2 つの構造体を比較するには、この関数を使用します。
構造体がパディングを含まないことがわかっている場合のみ、構造体のバイト単位の比較に memcmp
を使用します。通常、パディングが行われないようにするには、特定の属性または #pragma pack
などのプラグマを使用します。ただし、このような属性やプラグマは、必ずしもすべてのコンパイラでサポートされているとは限らず、コードの実装はそれぞれ異なります。構造体にビット フィールドが含まれる場合、このような属性やプラグマを使用しても、パディングを防ぐことはできません。
例
結果情報
グループ: プログラミング |
言語: C | C++ |
既定値: 手書きコードはオン、生成コードはオフ |
コマンド ライン構文: MEMCMP_PADDING_DATA |
影響度: Medium |
バージョン履歴
R2017a で導入