Reputation: 18572
So, I want to retain information of two short
into one int
for sending over the network later (this is just a demonstration, no network code here). I copied two bytes of each short
number into the prim
(primitive) variable.
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
int main()
{
unsigned int prim = 0;
short major = 0x0001;
short minor = 0x0000;
prim = 0;
memcpy(&prim, &major, 2);
memcpy(&prim+2,&minor, 2);
std::cout << "Prim: " << prim << std::endl;
return EXIT_SUCCESS
}
If I copy the major
first, then minor
(as written in the code above) later, I will get the correct output:
Prim: 1
Because my CPU is little endian, the binary representation should be:
10000000 00000000 00000000 00000000
However, if I change the order, meaning minor
first then major
later like this:
memcpy(&prim, &minor, 2);
memcpy(&prim+2,&major, 2);
I get a 0.
Prim: 0
Why? It is supposed to be:
00000000 00000000 10000000 00000000
Which is equal to 65536.
Upvotes: 0
Views: 359
Reputation:
Besides fixing the error in calculating correct poiters you may avoid all this pointer calculations by using unions:
#include <iostream>
union two_shorts_t {
unsigned int prim ;
struct shorts_t {
short major;
short minor;
} shorts;
} ;
int main ()
{
two_shorts_t values;
values.shorts.major=1;
values.shorts.minor=0;
std::cout << "Prim: " << values.prim << std::endl;
values.shorts.major=0;
values.shorts.minor=1;
std::cout << "Prim: " << values.prim << std::endl;
return 0;
}
Upvotes: 2
Reputation: 14392
A more portable way of putting integers into larger integers is by shifting.
uint16_t lo = 1;
uint16_t hi = 2;
uint32_t all = (hi << 16) + lo;
Upvotes: 5
Reputation: 523614
Because &prim + 2
points to 8 bytes (2 × sizeof(int)) after &prim
.
You need to cast it to a char*
to make the pointers increase by bytes.
memcpy((char*)&prim+2, &major, 2);
Upvotes: 4