Jump to content
    

Формирование int из массива char

Задача такая - есть массив test_buff, из подряд идущих 4-х элементов которого нужно сформировать переменную unsigned int.

 

unsigned char test_buff[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

unsigned char *tst_point = &test_buff[0];

unsigned int *tst;

 

tst = (unsigned int *)(tst_point + 2*sizeof(unsigned char)); //должны получить 0x06050403 = 100992003

 

Т.е. в *tst пытаюсь записать unsigned int, состоящий из байтов массива с 3-го по 6-й.

 

При исполнении этого кода на ARM-процессоре (ядро Cortex-M1) происходит зависание ядра (когда обращаюсь к адресу, некратному 4 байтам).

При исполнении этого же кода на ПК - все ок, *tst = 100992003, как и должно быть.

Компилятор Keil.

 

Есть идеи, как решить задачу?

Edited by AlexeyT

Share this post


Link to post
Share on other sites

Есть идеи, как решить задачу?

 

tst = (test_buff[0]<<24) + (test_buff[1]<<16) + (test_buff[2]<<8) + (test_buff[3]<<0);

Share this post


Link to post
Share on other sites

При исполнении этого кода на ARM-процессоре (ядро Cortex-M1) происходит зависание ядра (когда обращаюсь к адресу, некратному 4 байтам).

Ну естественно, Cortex-M1 не умеет делать доступ по неровным адресам.

 

При исполнении этого же кода на ПК - все ок, *tst = 100992003, как и должно быть.

Почему должно? Кто сказал? Просто x86 умеет делать доступ по неровным адресам. Скажем, даже взрослый SPARC из старенького сервера Sun не умеет.

 

Используйте memcpy:

unsigned char test_buff[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
unsigned int tst;
memcpy(&tst, test_buff + 2, sizeof(tst));

Share this post


Link to post
Share on other sites

tst = (test_buff[0]<<24) + (test_buff[1]<<16) + (test_buff[2]<<8) + (test_buff[3]<<0);

 

????

 

1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5].

2) test_buff[0]<<24 даст все нули, т.к. имеет 8 бит.

3) При чем тут арифметическое сложение, вообще непонятно.

 

 

Share this post


Link to post
Share on other sites

Хм, я думал, что там опечатка в коде.

unsigned int *tst;

 

tst = (unsigned int *)(tst_point + 2*sizeof(unsigned char)); //должны получить 0x06050403 = 100992003

 

Т.е. в *tst пытаюсь записать unsigned int, состоящий из байтов массива с 3-го по 6-й.

Нет. Этот код указателю tst присваевается адрес элемента другого массива &test_buff[2].

 

При исполнении этого кода на ARM-процессоре (ядро Cortex-M1) происходит зависание ядра (когда обращаюсь к адресу, некратному 4 байтам).

При исполнении какой конкретно строки кода происходит зависание?

 

1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5].

Это именно то, что я сделал в этом коде. Или вы int-переменной называете указатель? Ну так вас никто не поймёт, выражайтесь корректно.

Share this post


Link to post
Share on other sites

Определяем тип: структура с пятью элементами unsigned int.

Присваиваем указателю с типом структуры адрес вашего массива.

Работаем с элементами структуры.

Share this post


Link to post
Share on other sites

Какой-то разговор немого с глухим. Вы можете внятно сформулировать суть проблемы? Потому что в первоначальной формулировке терминологическая путаница и код неточный (не вижу строки, на которой может зависнуть).

Share this post


Link to post
Share on other sites

Нет. Этот код указателю tst присваевается адрес элемента другого массива &test_buff[2].

 

Само собой, указателю tst присваивается адрес массива test_buff[2].

При этом значение int-переменной я получаю, обратившись к *tst.

 

В каком именно месте происходит зависание, сказать не могу, процессор - 1986ВЕ1Т, там с дебагом туго.

 

Вот полный исходник тестового кода, на котором все виснет:

 

unsigned char test_buff[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

unsigned char *tst_point = &test_buff[0];

unsigned int *tst;

unsigned int temp;

 

tst = (unsigned int *)(tst_point + 2*sizeof(unsigned char)); //должны получить 0x06050403 = 100992003

 

temp = *tst;

 

printf("%d", temp);

 

Edited by AlexeyT

Share this post


Link to post
Share on other sites

????

 

1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5].

2) test_buff[0]<<24 даст все нули, т.к. имеет 8 бит.

3) При чем тут арифметическое сложение, вообще непонятно.

 

нельзя обращаться к 32х разрядным данным по невыровненным адресам (не кратным 4).

копируйте побайтно либо руками, как сказал Lmx2315, либо через memcpy.

 

3) что "+" что "|" тут без разницы.

2) компилятор вроде должен к int сначала привести, если не верите, приведите дополнительно руками или присваивайте по байтно через указатель:

 

int temp;

((unsigned char *)(&temp))[0] = test_buff[2];

((unsigned char *)(&temp))[1] = test_buff[3];

((unsigned char *)(&temp))[2] = test_buff[4];

((unsigned char *)(&temp))[3] = test_buff[5];

 

Share this post


Link to post
Share on other sites

__packed unsigned int *tst;

Самый лаконичный способ, на мой взгляд.

Как бы в GCC такое сделать?..

Share this post


Link to post
Share on other sites

Самый лаконичный способ, на мой взгляд.

Как бы в GCC такое сделать?..

 

а чем union не подходит??

Share this post


Link to post
Share on other sites

Самый лаконичный способ, на мой взгляд.

Как бы в GCC такое сделать?..

Универсально (компиляторонезависимо):

class {

unsigned char raw[4];

//здесь добавить перегрузку операторов приведения типа к unsigned и присваивания unsigned

};

Share this post


Link to post
Share on other sites

????

 

1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5].

2) test_buff[0]<<24 даст все нули, т.к. имеет 8 бит.

3) При чем тут арифметическое сложение, вообще непонятно.

1) Ну так вместо 0,1,2,3 в индексах поставьте 2,3,4,5

2) Не даст все нули, т.к. сдвинется в переменную типа int, и станет там самым старшим байтом

3) Совсем даже понятно, если не нравится арифметическое сложение, то можете объединить по ИЛИ, и ничего от этого не изменится - результат должен быть одинаковым

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...