2017-06-28 4 views
-1

そう仮定する1は、機能があります:関数を呼び出すときにバッファのデータ型が一致しないと(int *とunsigned int *)どうなりますか?

int somefunc(int* buf) 

が、我々はによってsomefuncを呼び出す:buf2はタイプunsigned intのデータを持っているallocaによって割り当てられたヒープバッファを、(これbuf2がであるポインタである

somefunc(buf2) 

タイプunsigned int*)。

これを行う危険性は何ですか?ここで何が問題になるでしょうか?私はこれがヒープ(バッファ)のオーバーフローと関係があるかもしれないと思うが、私はそれが何であるか分からない。コードには他にもいくつかの問題があるかもしれません。もしそうなら、私はこれらの問題についても知りたいと思っています。

コード例:ランダムファジングによって、私はオーバーフローの兆候を得ることができたが、私はオーバーフローが型の不一致によって発生する可能性がありますかわからないので、

void typecastfunc(FILE *p, int *buf, unsigned int index) { 
    unsigned int a; 
    for (a = 0; a < index; a++) { 
     if (fread(&buf[a], sizeof(unsigned int), 1, p) < 1) { 
      break; 
     } 
    } 
} 

void caller(char *filen) { 
    FILE *p = fopen(filen, "rb"); 
    if (!p) { 
     return; 
    } 
    unsigned int index; 
    fread(&index, sizeof(unsigned int), 1, p); 
    unsigned int *buf = alloca(index * sizeof(unsigned int)); 
    if (!buf) { 
     return; 
    } 
    typecastfunc(p, buf, index); 
} 

int main(int argc, char *argv[]) { 
    caller(argv[1]); 
} 

質問は、要求されています。他のコードは無害なので、型の不一致が原因であると想定しています。

+4

[最小限で完全であり、検証可能な例](http://stackoverflow.com/help/mcve)を作成してください。 )私たちを見せてください。宣言*をコード*として表示します。 –

+1

暗黙のキャストまたは変換が発生する可能性があります。暗黙的とは、通常、「詳細に計画されていない」ことを意味し、しばしば「望ましくない」ものになります。 intとunsigned intの間のキャスト/変換は、同じサイズで0-MAX_INTの範囲で同じセマンティクスがあるため、「しばしば動作します」。しかし、これらの「無害」は前提です。いずれかが適用されなくなると、問題をデバッグするのが難しくなります。それらのどれも公式に信頼できるものではありません。 – Yunnosch

+0

@Someprogrammerdudeサンプルコードを提供しました。 – NCL

答えて

0

バイナリストリームからデータをの配列に、サイズsizeof(unsigned int)のチャンクで読み込みます。

intのサイズがunsigned intのサイズと同じであることが保証されているため、適切なタイプを使用する方が良いでしょうが、この特定の間違いから予期する悪影響はありません。

値がintとして使用され、このタイプの範囲を超えた場合、unsigned intの表現で予期しない動作が発生する可能性がありますが、現在のアーキテクチャでは実際の問題はありません。

0

同じ整数型の符号付きバージョンと符号なしバージョンを混在させると、常に危険が生じます。暗黙の変換は、意図しない署名の変更を引き起こす可能性があります。あなたが署名したいときは計算が署名なしになることができます。符号なしタイプで表現可能な値は、符号付きタイプでは表現できない場合があります。等々。 同じタイプ(この場合int)の符号付き/符号なしのバージョンへポインタの特定の場合について

、離れ上述されたものから追加の危険性はありません。これらのポインタ変換は、C標準(1)の特別な例外として安全であるとみなされます。

したがって、int*からunsigned int*に変換すること自体は安全です。しかし、これはではなく、でも2つの異なるタイプを使用すると安全です。たとえば、int*からshort*への変換は、あらゆる種類の微妙なバグを引き起こす可能性があります。


(1)C標準スタンダードでは、C11。5/7(「厳密なエイリアシング規則」)は:

「オブジェクトは、その格納された値は、左辺値以下のタイプの1つを有する 式によってアクセスていなければならない:」
...
- 「オブジェクトの有効な型に対応する符号付きまたは符号なし型の型」

関連する問題