2010-12-07 3 views
3

EDIT: исправлен неправильный тип num2.Листинг массива символов в целое число

Здравствуйте,

У меня есть некоторые символьные массивы известного размера, который содержит исходные целочисленные данные, считанные из двоичного файла.

Размер всех этих массивов имеет размер целых чисел.

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

char arr1[4] = { ... }; 
char arr2[2] = { ... }; 

uint32_t num1 = *static_cast<uint32_t*>(arr1); /* OR num1 = *(uint32_t*)arr1 in C */ 
uint16_t num2 = *static_cast<uint16_t*>(arr2); /* OR num2 = *(uint32_t*)arr2 in C */ 

Спасибо!

+3

Поскольку это двоичный файл, вам лучше читать необработанные целые числа в массиве int. – chrisaycock 2010-12-07 19:19:56

+1

Никогда не объявляйте более одной переменной за раз. Это может привести к тонким ошибкам. https://www.securecoding.cert.org/confluence/display/seccode/DCL04-C.+Do+not+declare+more+than+one+variable+per+declaration – 2010-12-07 19:23:22

+0

Непосредственная заливка памяти символов целому числу работает только на процессорах с выравниванием байтов, а не выравниванием слов. Если вы только/всегда работаете на Intel x86, это не будет проблемой. – 2010-12-07 19:36:26

ответ

3

Это технически безопасно, но есть несколько вещей, которые я хотел бы рассмотреть следующие вопросы:

  • Добавить время компиляции утверждает, проверить размеры. Вы уверены, что ваш массив символов равен sizeof (your_int_type)? Ваш num2 - отличный пример того, почему это важно - ваша опечатка вызовет неопределенное поведение.
  • Рассмотрите расстановку. Вы уверены, что ваш массив символов находится на 4-байтной границе (если ваш int равен 4 байтам)? PowerPC, например, сработает, если вы попытаетесь прочитать int из неглавного указателя.
1

Это должно быть безопасным:

char arr1[4] = { ... }; 

uint32_t num1; 

memcpy(&num1, arr1, sizeof num1); 

Но почему arr2 только 2 байта большой? Это опечатка?

0

Более безопасный подход заключается в использовании макроса (например, MAKEDWORD), чтобы поместить байты в их надлежащем порядке.

0

Если вы уверены, что массивы правильно выровнены, тогда не должно быть проблемы (учитывая точность).

В коде, однако, я не знаю, что вы делаете с arr2, так как это 16 бит, и вы читаете 32-битное количество от него.

0

Да, это должно работать нормально (в соответствии с вашим допущением о контенте), поскольку представление этих байтов в памяти одинаково независимо от того, интерпретируется ли оно как массив байтов или целое число.

Действительно, все, что вы делаете, это изменение типа, а не данных.

5

Вы должны использовать союз.

union charint32 { 
    char arr1[4]; 
    uint32_t num; 
}; 

Это упростит хранение и литье для вас.

Смежные вопросы