Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Byte setting an unsigned short

Tags:

c++

memset

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?

like image 971
Bogu Wei Avatar asked Mar 11 '23 15:03

Bogu Wei


2 Answers

&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;
}
like image 102
MikeCAT Avatar answered Mar 20 '23 19:03

MikeCAT


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 */
like image 24
Rudy Velthuis Avatar answered Mar 20 '23 20:03

Rudy Velthuis