简体   繁体   中英

Reading from void pointer — reinterpret_cast okay?

I have been debugging my code for some time now and I need a sanity check that reinterpret_cast is not the issue. Its been a while since I have used C/C++ and I may forgetting the basics.

In my function, I have been given some amount of generic data void *data From other parameters passed in, I know the size of the data and where certain types are offset'ed. For example, data has a size of 12 bytes: first 4 bytes are an int, the next 4 bytes are chars, and the last 4 bytes are ints.

Question: How would I grab each peace of data (int, char, char, char, char, int) from data? I have, so far, been using reinterpret_cast and it works! However can such a instance come up where my values (memFirst4, memA, memB, etc.) are not what I expected because I am using reinterpret_cast?

void *data = malloc((sizeof(int)*3)); // 12 bytes .. my compiler has ints as 4 bytes
int first4 = 8075;
char a = 'a';
char b = 'b';
char c = 'c';
char d = 'd';
int last4 = 981;
memcpy(data,&first4,sizeof(int)); // copy first4 into memory
memcpy(data+sizeof(int)+sizeof(char)*1,&a,sizeof(char)); // copy char a into memory
memcpy(data+sizeof(int)+sizeof(char)*2,&b,sizeof(char)); // copy char b into memory
memcpy(data+sizeof(int)+sizeof(char)*3,&c,sizeof(char)); // copy char c into memory
memcpy(data+sizeof(int)+sizeof(char)*4,&d,sizeof(char)); // copy char d into memory
memcpy(data+sizeof(int)+sizeof(char)*4+sizeof(int),&last4,sizeof(int)); // copy last4 into memory

int memFirst4 = *reinterpret_cast<int *>(data);
char memA = *reinterpret_cast<char *>(data+sizeof(int)+sizeof(char)*1);
char memB = *reinterpret_cast<char *>(data+sizeof(int)+sizeof(char)*2);
char memC = *reinterpret_cast<char *>(data+sizeof(int)+sizeof(char)*3);
char memD = *reinterpret_cast<char *>(data+sizeof(int)+sizeof(char)*4);
int memLast4 = *reinterpret_cast<int *>(data+sizeof(int)+sizeof(char)*4+sizeof(int));
free(data);

Your solution will work, but is pretty risky (easy to make mistake, copy one byte less or more). Therefore, I would recomment a union:

#pragma pack(1)
union myData
{ 
  char data[12];
  struct fields 
    { 
      uint8_t i[4];
      char c[4];
      uint8_t i2[4];
    } u_fields;
}
#pragma pack(pop) 

Union allows you to read the same chunk of memory as different types (in this case using char[12] data and fields struct).

Have a look here for more info

You should not use reinterpret_cast.Casting some pointer from void* is not allowed using reinterpret_cast.

When you want to cast from void* to something else, you can use static_cast. But remember converting from one type to another (not the same) type using void* in between will yield to an unspecified pointer value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM