Suppose I have a C-style array of type unsigned char
:
unsigned char * c = (unsigned char *) malloc(5000 * sizeof(unsigned char));
for(int i = 0; i < 5000; i++)
c[i] = (unsigned char) ((i >> (i%4 * 8)) & 0xFF);
Suppose I have a pointer offset to a position which starts a 4 byte integer:
// pseudo code
unsigned int i = c + 10; // 10 = pointer offset, let's say.
If I want to load i
up with the correct number, I can do:
unsigned int i = (*(c+10) << 24) + (*(c+11) << 16) + (*(c+12) << 8) + (*(c+13));
But shouldn't I just be able to, somehow, do this using casts?
// pseudo code -- I haven't gotten this to work yet:
int i = (unsigned int) (*((void *)(c+10));
// or maybe
int i = *((unsigned int*)((void *)(c+10)));
In short, what is the cleanest, most effective way to transition the four bytes to an unsigned int
in a C-style byte array?
The proper way to do this is to use memcpy:
unsigned int i;
std::memcpy(&i, c + offset, sizeof(unsigned int));
On architectures that support unaligned variable access (like x86-64), this will be optimized into a simple pointer dereference, but on systems that don't support unaligned access (such as ARM), it will do the proper thing to get the value out.
See for example: https://gcc.godbolt.org/z/l5Px4G . Switch the compiler between gcc for x86 and arm and see the difference in instructions.
Keep in mind the idea of endianness if you're getting the data from some external source. You may have to flip the bytes of the integer around for the value to make sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With