1

0x48656c6c6fすべてのバイトが string 内の各文字の ASCII 値を表す16 進値があります"Hello"charこれらの値を挿入したい配列もあります。

小さい 16 進数値 (たとえば、0x48656c6cを表す) がある場合、配列を"Hell"印刷すると正しい出力が得られました。charただし、次のコードは"olle"(リトル エンディアンで) 表示されますが、表示されません"olleH"。どうしてこれなの?

#include <iostream>                           
#include <cstring>                             

int main()
{
    char x[6] = {0};
    int y = 0x48656c6c6f;

    std::memcpy(x, &y, sizeof y);

    for (char c : x)
        std::cout << c;
}

デモはこちら。

4

4 に答える 4

5

おそらくint、あなたのプラットフォームでは 4 バイトです。

エラーもある場合、ideone は警告を表示します: http://ideone.com/TSmDk5

prog.cpp: 関数 'int main()' 内: prog.cpp:7:13: 警告: 暗黙的な定数変換でのオーバーフロー [-Woverflow] prog.cpp:12:5: エラー: 'error' はこれで宣言されていません範囲

于 2013-07-05T14:21:13.360 に答える
5

おそらくintあなたのマシンでは32ビットです。これは、定数の上位バイトがカットされていることを意味します。だから、あなたint y = 0x48656c6c6f;は実際にint y = 0x656c6c6f;(ちなみに、それは符号付き整数のオーバーフローとしてカウントされるため、未定義の動作と見なされると思います。ここで動作を定義するには、 を使用する必要がありますunsigned int)。

したがって、リトル エンディアン マシンでは、y のメモリ内表現は であり6f 6c 6c 65、これが にコピーさxれ、「olle」が表示されます。

問題を「修正」するには、より大きなサイズの整数を使用する必要があります。これは、プラットフォームによってはlong longint64_tまたは同様のものになる場合があります。このような場合、x( ) を十分に大きくchar x[sizeof(y)+1]={0}してバッファ オーバーフローを回避するか、memcpyに収まるバイトのみをコピーするようにを変更してxください。

また、これらの種類のトリックを実行するときは常にunsigned整数を使用してください。UB を回避し、オーバーフローの場合に予測可能な動作を得ることができます。

于 2013-07-05T14:23:23.423 に答える
1
int y = 0x48656c6c6f;

intおそらくあなたのマシンが32ビットであるため、それを保存することは保証されていません。long long代わりに使用

于 2013-07-05T14:22:34.077 に答える