Unsigned char array casting to long long [closed]
-
21-12-2019 - |
Question
I'm not sure if this is correct, I have tested it and seems that some bytes are off... Basically, I have the following:
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
Would anyone mind pointing out where I went wrong? Thank you.
Solution
You're setting nNewValue
to the address of szBuffer
, instead of reading data from that address. Use:
long long nNewValue = *reinterpret_cast<long long*>(szBuffer);
OTHER TIPS
Change this statement
long long nNewValue = reinterpret_cast<long long>(szBuffer);
to
long long nNewValue = *reinterpret_cast<long long *>(szBuffer);
Here's a modified version of your program that works on my system (expanded to a complete program):
#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 first two parameters are of type void*
, so you don't need to cast them; if you do cast them (is that conversion deprecated in C++?), you should cast to void*
, not char*
.
The assignment to nNewValue
converts the address of the buffer to long long*
, and then dereferences the converted value.
But this is a bad idea. g++ gives me a warning on the dereference of the converted pointer:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Furthermore, there is no guarantee that szBuffer
, which is an array of unsigned char
, is correctly aligned so its first few bytes can safely be treated as a long long
object. The x86 or x86_64 system you're most likely using tolerates misaligned memory accesses, but not all systems do so.
Pointer casts are often unsafe unless you know exactly what you're doing.
If you want to reinterpret part of a character array as an object of some other type, you can use a union if you really need to interpret the memory itself as a different type of object, or use memcpy
. (Even so, be sure that you really need to do this; it's likely that you don't. Most of the time, if you want to store a long long
object, you should just define a long long
object.)