2010-12-07 9 views
3

EDIT:間違ったタイプのnum2が修正されました。文字配列を整数にキャストする

こんにちは、

私は、バイナリファイルから読み取る生整数データが​​含まれている既知のサイズのいくつかの文字配列を持っています。

これらの配列のサイズはすべて整数です。

生データのエンディアンとこのコードを実行しているコンピュータが一致していると仮定して、以下の操作が安全で正確であるかどうかを質問したいと思います。

char arr1[4] = { ... }; 
char arr2[2] = { ... }; 

uint32_t num1 = *static_cast<uint32_t*>(arr1); /* OR num1 = *(uint32_t*)arr1 in C */ 
uint16_t num2 = *static_cast<uint16_t*>(arr2); /* OR num2 = *(uint32_t*)arr2 in C */ 

ありがとうございます!

+3

バイナリファイルなので、生の整数をintの配列に読み込むほうがよいでしょう。 – chrisaycock

+1

一度に複数の変数を宣言しないでください。微妙なバグにつながる可能性があります。 httwww://www.securecoding.cert.org/confluence/display/seccode/DCL04-C.+Do+not+declare+more+than+one+variable+per+declaration –

+0

文字メモリを整数に直接キャストするワード整列ではなく、バイト整列のCPU上。もしあなたがIntel x86のみで動作しているのであれば、それは問題ではありません。 –

答えて

3

それは技術的に安全ですが、私は考えるだろうがいくつかあります:

  • コンパイル時の追加サイズを確認するために主張しています。あなたのchar配列がsizeof(your_int_type)と等しいことを確かですか? num2は、これが重要な理由の素晴らしい例です。タイプミスが原因で未定義の動作が発生する可能性があります。
  • アライメントを考慮してください。あなたのchar配列が4バイト境界にあることを確かめますか?(あなたのintが4バイトであると仮定して)?アライメントされていないポインタからintを読み込もうとすると、PowerPCはクラッシュします。
+0

対応する整数の型は、私のプログラムでいくつかのテンプレートメタプログラミングコードで決定されるので、正しい型が保証されています。 –

+1

char配列が本当に4バイト境界であることを確認する方法はありますか? –

+0

+1。私は整列についてそれを知らなかった... – Cameron

1

これは安全でなければならない:

char arr1[4] = { ... }; 

uint32_t num1; 

memcpy(&num1, arr1, sizeof num1); 

しかし、なぜ大きなarr2のみ2バイトのですか?それはタイプミスですか?

+1

バイト内にいくつのビットがあるか分からない。 –

+0

@冗談:コードの配備場所を管理している限り、そうすることができます。 –

0

より安全なアプローチは、マクロ(例:MAKEDWORD)を使用してバイトを正しい順序で配置することです。

0

配列が適切に整列されていることが確かであれば、問題はないはずです(エンディアンを指定してください)。

しかし、私はarr2で何をしているのか分からない。なぜなら、それは16ビットであり、それから32ビットの量を読み込んでいるからだ。

0

はい、メモリ内のこれらのバイトの表現が、バイト配列か整数かにかかわらず同じであるので、エンディアンの前提の下ではうまくいくはずです。

実際には、データではなくタイプを変更するだけです。

5

ユニオンを使用する必要があります。

union charint32 { 
    char arr1[4]; 
    uint32_t num; 
}; 

これにより、保存とキャストが簡略化されます。

+1

バイトオーダーが同じであれば、これは機能し、データ型の整列の問題は発生しません。 –

+0

+1。これは動作します。これはC++標準に準拠していませんが、おそらく最も違反しているルールの1つです。 – EboMike

関連する問題