Amumu
Amumu

Reputation: 18572

Copy bytes from smaller types to bigger type

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

Answers (3)

user184968
user184968

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

stefaanv
stefaanv

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

kennytm
kennytm

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

Related Questions