Как преобразовать массив указателей char в массив указателей int в C - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть 8-байтовый указатель на символ, в котором хранятся 2 целых числа. как сохранить его в указателе массива int, чтобы в массиве int 1-е целое число было array[0], а 2-е целое - array[1].

Код, который я до сих пор делал:

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]);

Когда я сделал это, ожидаемый результат был 16 и 18, но я неожиданно получил 268435456 и 301989888.

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Предполагая, что вы знаете о строгом нарушении правила псевдонима , ваш код будет генерировать ожидаемый результат в архитектуре big endian , в которой хранятся четыре байта, составляющие целое число начиная с самого старшего байта:

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

Но вы, очевидно, выполняете свой код на машине с архитектурой little endian :

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

Итак, чтобы сместить ваше целое число в массиве char, вам необходимо:

  1. Байт 0 из i, то есть i >> (8 * 0), имеет индекс 0 массива wirte_buff
  2. Байт 1 из i, то есть i >> (8 * 1), имеет индекс 1 из wirte_buff array
  3. Байт 2 из i, то есть i >> (8 * 2), является с индексом 2 из wirte_buff массив
  4. Байт 3 из i, то есть i >> (8 * 3), находится с индексом 3 из wirte_buff массив

Это переводит в

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

и то же, конечно, для j:

wirte_buff[4+n] = (j >> 8*(n)) & 0xFF;
0 голосов
/ 28 апреля 2020

Этот код неверен во многих отношениях.

  • char * wirte_buff= (char*) malloc(8*sizeof(char*)); выделяет 8 char* и данных нет. Эти указатели нигде не назначаются, поэтому они остаются неинициализированными.
  • i >> ... et c выполняет побитовые операции над типом со знаком, что всегда неверно. Если значение отрицательное, вы получите результаты, определенные реализацией.
  • Если вы конвертируете значение int в char, тогда char имеет подпись, определяемую реализацией, так что вы не ' не знаю, в итоге вы получили отрицательное значение или, возможно, переполнение / недополнение.

  • Если этого избежать, вы не можете прочитать char обратно через другой тип с помощью (int*) wirte_buff; ... intArray[0], потому что это не совместимые типы. Вы можете прочитать смещенные данные. Вы также нарушите строгий псевдоним указателя, см. Что такое правило строгого псевдонима?

Нет ожидаемого поведения размещенного кода, и я сомневаюсь, что вы можете его спасти , Вам придется переписать это с нуля и особенно избегать всех подозрительных преобразований.

...