Понимание типа символов uint32_t (в байтах) - PullRequest
0 голосов
/ 24 августа 2018

Допустим, у нас есть это:

int main()
{

    int32_t* value = (uint32_t*)malloc(sizeof(uint32_t));
    uint32_t array[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    *value = *(uint32_t*)((char*)array + 8);

    printf("Value is: %d\n", *value);

    return 0;
}

Значение в этом случае будет 3. Почему именно это? Если мы приведем uint32_t к char, значит ли это, что один символ равен 4 байта в uint32_t и, следовательно,

array[9] = {0, 4, !!8!!, 12, 16, 20, 24, 28, 32};

Может ли кто-нибудь попытаться объяснить это?

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Probable memory layout

Вы создали array[9] занимает 36 байтов.Он хранится в памяти, как показано в первом ряду.3 сохранить, как я представлял (зависит от компилятора).

После того, как вы ввели его в символьную память, вы увидите, как показано во 2-й строке.

Теперь, если вы добавите 8, он перейдет на 8-ю позицию, что означает после 02, потому что, (char*)array + 8 рассматривается как type+8.Здесь type равно char.Таким образом, он перемещается только на 8 байтов.

Затем память от 8 до 35 размечается в uint32_t, а первое значение сохраняется в *value.Так будет 3 только.

0 голосов
/ 24 августа 2018

Когда вы инициализируете массив, каждый инициализатор устанавливает элемент массива независимо от того, сколько байтов занимает каждый элемент.

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

-----------------------------------------------------------------
| 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | ...
-----------------------------------------------------------------

|      [0]      |      [1]      |      [2]      |      [3]      | ...

Каждое значение типа uint32_t имеет длину 4 байта, а младший байт занимает первое место.

Когда вы делаете (char*)array который преобразует array (преобразованный в указатель) в char *, поэтому любая арифметика указателя на char * увеличивает адрес на величину char, которая равна 1.

(char*)array + 8 указывает здесь:

(char*)array + 8 ------------------
                                  v
-----------------------------------------------------------------
| 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | ...
-----------------------------------------------------------------

|      [0]      |      [1]      |      [2]      |      [3]      | ...

Этот указатель затем преобразуется в uint32_t * и разыменовывается, поэтому он читает значение 3.

...