2016-11-18 3 views
0

Существует массив arr с выделенной памятью для двух short s (всего 4 байта). Затем я заполняю эти два элемента ffff и eeee соответственно. После того, как я пытаюсь перебрать одну и ту же выделенную память, как было выделено для 4 char s (также всего 4 байта, но теперь я могу быть в состоянии искать элементы по 1 байт). Как видно из вывода, он не показывает, что я ожидаю (получаю тот же 0xeeeeffff, разделенный на 4 отдельных элемента). Что не так с кодом?Как перебрать массив, интерпретирующий его элемент как другой тип?

short *arr = malloc(sizeof(short) * 2); 
    *arr = 0xeeee; 
    *(arr + 1) = 0xffff; 
    printf("%p\n", &arr[0]); 
    printf("%p\n", &arr[1]); 
    // convert 
    char * cnv = (char *)arr; 
    printf("=======\n"); 
    for (int i = 0; i < 4; i++) { 
    printf("%p\n", cnv); 
    printf("%x\n", *cnv); 
    cnv++; 
    } 

Выход:

0x759010 
0x759012 
======= 
0x759010 
ffffffee # expect 'ee' 
0x759011 
ffffffee # expect 'ee' 
0x759012 
ffffffff # expect 'ff' 
0x759013 
ffffffff # expect 'ff' 
+1

'short' и' char' переданы printf через '...' передаются как 'int'. Вот как работает «...». Вам нужно использовать ''% hhx'' для интерпретации этого 'int' как char (в gcc в любом случае). – Arkadiy

ответ

1

%x ожидает unsigned int, не char, и, таким образом, ваша программа имеет неопределенное поведение. Вам нужно %hhx.

+1

[Демо с несколькими исправлениями] (https://ideone.com/abZOVz) –

+0

Почему вы выбрали указатель (unsigned short *) для (void *) здесь 'printf ("% p \ n ", (void *) & обр [0]); '? –

+0

@TimurFayzrakhmanov: Потому что так работает 'printf'. Ваш исходный код имеет неопределенное поведение. См. Руководство. –

2

Кажется, что char подписан тип на вашей платформе. Шестнадцатеричный 0xee рассматривается как отрицательное число (-18). Когда этому числу присваивается целое число, это двоичное представление таково, что оно равно 0xffffffee в шестнадцатеричном формате.

То же самое происходит с 0xff.

Если вы печатаете его с использованием %d, вы можете увидеть отрицательное значение на выходе.

printf("%x %d\n", *cnv, *cnv);