Long longへのUnsigned char配列のキャスト[closed]
-
21-12-2019 - |
質問
これが正しいかどうかはわかりませんが、テストしましたが、一部のバイトがオフになっているようです。..基本的に、私は次のものを持っています:
unsigned char szBuffer[1024] = {0};
long long nValue = 1334553536;
memcpy(szBuffer, (char*)&nValue, sizeof(long long));
//
long long nNewValue = reinterpret_cast<long long>(szBuffer);
printf(nNewValue); //prints out a smaller number than previously stated
誰かが私が間違っていた場所を指摘してもいいですか?お疲れさまでした。.
解決
あなたは設定しています nNewValue
のアドレスに szBuffer
, 、そのアドレスからデータを読み取る代わりに。使用:
long long nNewValue = *reinterpret_cast<long long*>(szBuffer);
他のヒント
この文を変更する
long long nNewValue = reinterpret_cast<long long>(szBuffer);
に
long long nNewValue = *reinterpret_cast<long long *>(szBuffer);
これが動作するプログラムの修正版です 私のシステム上で (完全なプログラムに拡張):
#include <iostream>
#include <cstring>
int main() {
unsigned char szBuffer[1024] = {0};
long long nValue = 1334553536;
std::memcpy(szBuffer, &nValue, sizeof(long long));
long long nNewValue = *(reinterpret_cast<long long*>(&szBuffer));
std::cout << nValue << "\n" << nNewValue << "\n";
}
memcpy
'sの最初の二つのパラメータはタイプです void*
, 、だからあなたはそれらをキャストする必要はありません;あなたがそれらをキャストした場合(その変換はC++で非推奨ですか?)、キャストする必要があります void*
, 、ない char*
.
への割り当て nNewValue
を変換します。 住所 バッファの long long*
, そして、変換された値を逆参照します。
しかし、これは悪い考えです。g++は、変換されたポインタの逆参照に関する警告を私に与えます:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
さらに、以下の保証はありません szBuffer
, 、これはの配列です unsigned char
, は、最初の数バイトを安全に扱うことができるように正しく整列されています。 long long
オブジェクト。おそらく使用しているx86またはx86_64システムは、ずれたメモリアクセスを許容しますが、すべてのシステムがそうするわけではありません。
あなたが知っていない限り、ポインタキャストはしばしば安全ではありません その通り! 何をしてるんだ?
文字配列の一部を他の型のオブジェクトとして再解釈する場合は、メモリ自体を別の型のオブジェクトとして解釈する必要がある場合は、unionを使 memcpy
.(そうであっても、あなたが本当にこれを行う必要があることを確認してください;それはあなたがしない可能性があります。ほとんどの場合、あなたが保存したい場合は long long
オブジェクト、あなただけの必要があります 定義 a long long
オブジェクト。)