0

I have an 8 byte char pointer that has 2 integers stored inside it. how do I store it in a int array pointer so that the int array has the 1st integer is in array[0] and the 2nd integer is in array[1].

The code I made so far:

char * wirte_buff= (char*) malloc(8*sizeof(char*));
int i, j;
i =  16;
j = 18;

/*separates integer i and integer j into 4-bytes each*/ 
for(n=0; n<=3; n++){
  wirte_buff[n] = (i >> 8*(3-n)) & 0xFF;
  wirte_buff[4+n] = (j >> 8*(3-n)) & 0xFF; 
}

int* intArray = (int*) wirte_buff; //puts char pointer to 
printf("intArray[0] value is %d \n", intArray[0]);
printf("intArray[1] value is %d \n", intArray[1]);

When I did this it the expected result was 16 and 18, but I unexpectedly got 268435456 and 301989888.

Roberto Caboni
  • 6,078
  • 10
  • 19
  • 34
  • It might be of value to you that `16` is `0x10` and `0x10000000` is equal to `268435456`. Similar `18` is `0x12` in hex, and `0x12000000` is `301989888` in base 10. – KamilCuk Apr 27 '20 at 21:39
  • You can debug the code and see what's happening in memory at the address of `write_buff`. – faressalem Apr 27 '20 at 21:57
  • Strictly speaking, `int* intArray = (int*) wirte_buff; //puts char pointer to ` is [a strict aliasing violation](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) and undefined behavior. You can not safely refer to a `char` array as an `int` unless the memory referred to is actually an `int` variable. In this case, it's not. Bad code like this tends to get taught by a lot of people who should know better because x86 systems are very forgiving with misaligned accesses and usually let you get away with it. – Andrew Henle Apr 27 '20 at 22:34
  • (cont) [But not always](https://stackoverflow.com/questions/46790550/c-undefined-behavior-strict-aliasing-rule-or-incorrect-alignment). – Andrew Henle Apr 27 '20 at 22:34

2 Answers2

1

Assuming you are aware of the strict aliasing rule violation, your code would generate the result you expect in a big endian architecture, in which the four bytes composing an integer are stored starting from the most significant byte:

------------------------------------------------------------------------------
| byte3 (bit 24:31) | byte2 (bit 16:23) | byte1 (bit 8:15) | byte0 (bit 0:7) |
------------------------------------------------------------------------------

But you are apparently running your code in a little endian architecture machine:

------------------------------------------------------------------------------
| byte0 (bit 0:7) | byte1 (bit 8:15) | byte2 (bit 16:23) | byte3 (bit 24:31) |
------------------------------------------------------------------------------

So, in order to displace your integer in the char array, you need that:

  1. The byte 0 of i, that is i >> (8 * 0), is at index 0 of wirte_buff array
  2. The byte 1 of i, that is i >> (8 * 1), is at index 1 of wirte_buff array
  3. The byte 2 of i, that is i >> (8 * 2), is at index 2 of wirte_buff array
  4. The byte 3 of i, that is i >> (8 * 3), is at index 3 of wirte_buff array

This translates in

wirte_buff[n] = (i >> 8*(n)) & 0xFF;

and the same, of course, for j:

wirte_buff[4+n] = (j >> 8*(n)) & 0xFF;
Roberto Caboni
  • 6,078
  • 10
  • 19
  • 34
0

This code is wrong in many ways.

  • char * wirte_buff= (char*) malloc(8*sizeof(char*)); allocates 8 char* and no data. You don't assign these pointers anywhere, so they remain uninitialized.
  • i >> ... etc performs bitwise operations on a signed type, which is always wrong. If the value is negative, you end up with implementation-defined results.
  • Should you convert the int value into char, then char has implementation-defined signedness so you don't know if you end up with a negative value or possibly an overflow/underflow.

  • Should you avoid that as well, you can't read a char back through another type with (int*) wirte_buff; ... intArray[0] because these are not compatible types. You might read misaligned data. You will also violate strict pointer aliasing, see What is the strict aliasing rule?

There is no expected behavior of the posted code and I doubt you can salvage it. You will have to re-write this from scratch and especially avoid all the fishy conversions.

Lundin
  • 155,020
  • 33
  • 213
  • 341