How to make an index point for two or more consecutive cells

Suppose I have a uint8_t pointer for the third element in the array, {1, 2, 4, 5}, so *p is 4. How can I get it to point to 4 and 5 so that *p is 45. Is this possible ? I'm currently picking on. Here is what I do, for example. if the data is my array {1, 2, 4, 5}, and I want to get 4 and 5.

 uint8_t dummyAddress = data[2]; dummyAddress = *((uint16_t*) dummyAddress); *p = *dummyAddress; 

I understand that p should now point to 4 and 5, but I'm not sure. Instead, I get a seg error when I execute the second line. p is a uint64_t * const . It works to get one byte, but when applying one logic to two bytes, I do not understand.

+5
source share
3 answers

You can do it:

 uint8_t data[] = { 1, 2, 4, 5 }; uint8_t *p8 = &data[2]; uint16_t u16 = *(uint16_t*)p8; 

Then (uint16_t*)p8 will point to data[2] and data[3] . But you cannot easily access *(uint16_t*)p8 . Firstly, this is because p8 cannot be aligned on the uint16_t border. In this case, some processor throws an exception. Secondly, even if you can access *(uint16_t*)p8 , you can get different results depending on the byte order of the processor (big endian / little endian). You can get 0x0405 or get 0x0504.

Also note that in your line

 dummyAddress = *((uint16_t*) dummyAddress); 

you first reinterpret dummyAddress as a pointer to uint16_t , and then uint16_t it, so you return uint16_t and save it in dummyAddress . This is clearly not what you wanted to do. If this really compiles, please consider compiling with a higher warning level and take a look at each compiler warning (and just ignore it if you understand it and are sure that this is not a programming error).

By the way, you cannot get the pointer p , where *p==45 , as you request in your question.

Also, as mch said: What is a strict alias rule?

+4
source

If I understand what you are doing, then yes, you can access both bytes by casting to uint16_t , but at the same time you will encounter problems (or problems with endianess) with the way the byte order is stored in memory, and also violate strict smoothing. This will probably return an answer you did not suspect. For instance:

 #include <stdio.h> #include <stdint.h> int main (void) { uint8_t array[] = {1,2,3,4}; uint8_t *p = array + 2; printf ("\n the uint8_t answer : %hhd\n", *p); printf (" the uint16_t answer : %hd\n\n", *(uint16_t *)p); printf ("**note: the will cast result in bytes 4, 3" " (or (4 << 8 | 3) = 1027)\n\n"); return 0; } 

Output

 $ ./bin/cast_array the uint8_t answer : 3 the uint16_t answer : 1027 **note: the cast will result in bytes 4, 3 (or (4 << 8 | 3) = 1027) 

Bytes are stored in memory on my system in little endian order. Therefore, when clicking on uint16_t it expects to find the least significant , most significant bytes. Which in the above example with 34 in memory, cast will interpret the actual order as 43 , which will result in a value of 1027 instead of (3 << 8) | 4 = 772 (3 << 8) | 4 = 772 .

As already noted, you will break the rules associated with a strict alias, where trimming types by casting to anything other than char results in undefined behavior. The results of all these actions are hardware and compiler dependent and should not be used for anything other than training.

+1
source

You must write:

 uint_8_t *dummyAddress= &data[2]; uint_16_t *dummyAddress2= (uint16_t *) dummyAddress; uint_16_t p= *dummyAddress2; 

but note that due to "endianness" you can get two uint_8 in the wrong order, that is, like {data[3], data[2} .

0
source

Source: https://habr.com/ru/post/1235140/


All Articles