Почему эта оболочка malloc делает это с размером запрошенной памяти? размер = (размер + 3) & ~ 3; - PullRequest
3 голосов
/ 30 марта 2019

Я просматриваю исходный код DOOM и нашел эту строку.

void *
Z_Malloc
        (int size,
         int tag,
         void *user) {
    int extra;
    memblock_t *start;
    memblock_t *rover;
    memblock_t *newblock;
    memblock_t *base;

    size = (size + 3) & ~3; // Why is it doing this?
...

Я вижу, sizeof много использовал для создания смещения байтов, но я никогда не видел этого.

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

Что он делает?

Ответы [ 2 ]

6 голосов
/ 30 марта 2019

size = (size+3) & ~3 округляет размер до ближайшего кратного 4.

Это делается для того, чтобы все блоки были кратны 4 байтам, а каждый блок начинался с адреса, кратного 4.

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

Чтобы увидеть, как работает округление, скажем, что size = 4x-a , где 0 <= a <= 3 </em>. У нас есть:

размер + 3 = 4x + (3-a) , где 3-a также находится между 0 и 3 .

~ 3 - битовая маска, включающая все биты, кроме 2 0 и 2 1 , таким образом, операция & оставит только кратное 4:

(размер + 3) & ~ 3 = 4x

2 голосов
/ 30 марта 2019

Если вы запустите это, это будет очевидно:

for(int i=0; i<30; i++)
    printf("%d ", (i+3) & ~3);

Вывод:

0 4 4 4 4 8 8 8 8 12 12 12 12 16 16 16 16 20 20 20 20 24 24 24 24 28 28 28 28 32

Округляется до ближайшего 4.

Это сделано так.Выполнение x = x & ~3 установит два младших бита x в ноль.Если мы примем 8-битные числа для простоты, то 3 будет сохранен как 00000011, что означает, что ~ 3 будет 11111100, поэтому при выполнении логического и с этим номером последние два бита будут установлены в ноль.Само по себе это округление до ближайших четырех, потому что 4 двоичных числа равны 100. Если сначала добавить 3, вместо этого будет округление вверх.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...