Bogu Wei
Bogu Wei

Reputation: 53

Byte setting an unsigned short

I'm trying to set the bytes in an unsigned short variable individually using memset:

#include <cstring>
#include <iostream>

int main()
{
  unsigned short test2; // 2 bytes

  std::cout << "size of test2: " << sizeof(test2) << std::endl;

  memset(&test2, 0, 2); 
  memset(&test2, 0x4D, 1);                                                               
  memset(&test2+1, 0x42, 1); 

  std::cout << "value: " << test2 << std::endl;

  return 0;
}

The output I'm getting is:

size of test2: 2
value: 77

77 is 0x4D. So for some reason it's not picking up the 0x42 that I'm trying to set on the second byte of the variable. Why is that?

Upvotes: 4

Views: 850

Answers (2)

Rudy Velthuis
Rudy Velthuis

Reputation: 28826

The expression &test2+1 is scaled by the size of test, so you are setting the unsigned short that follows test2 in memory, and not the top byte of test2. Since this unsigned short you are referencing is not allocated, you are invoking undefined behaviour.

You will have to cast &test2 to char * to get a scaling of 1 (byte):

memset((char *)&test + 1, 0x42, 1);

Another way to do this without using memset():

unsigned short setbytes(unsigned char hi, unsigned char lo)
{
    return hi << 8 | lo;
}

...    

    unsigned short test2 = setbytes(0x42, 0x4D); /* --> 0x424D */

Upvotes: 1

MikeCAT
MikeCAT

Reputation: 75062

&test2+1 will actually progress the address by sizeof(test2), which is 2, and move the pointer to out-of-range.

Try this with casting to char*:

#include <cstring>
#include <iostream>

int main()
{
  unsigned short test2; // 2 bytes

  std::cout << "size of test2: " << sizeof(test2) << std::endl;

  memset(&test2, 0, 2); 
  memset(&test2, 0x4D, 1);                                                               
  memset((char*)&test2+1, 0x42, 1); 

  std::cout << "value: " << test2 << std::endl;

  return 0;
}

Upvotes: 6

Related Questions