Интервал выделения памяти

struct Thing
{
    int member1;
    int member2;
};

struct Thing* heap()
{
    struct Thing* heap_thing = (struct Thing*)malloc(sizeof(struct Thing));

    heap_thing->member1 = 1;
    heap_thing->member2 = 2;

    printf("%p, %p, %p\n", heap_thing, &(heap_thing->member1), &(heap_thing->member2));

    return heap_thing;
}

int main(int argc, char* argv[])
{
    struct Thing* ptr = 0;
    for (int i = 0; i < 5; ++i)
    {
       ptr = heap();
       free(ptr);
    }        
    return 0;
}

Я ожидаю, что напечатанные адреса памяти будут что-то вроде: (потому что struct Thing 8 байт)

0x000008, 0x000008, 0x00000c

0x000010, 0x000010, 0x000014

0x000018, 0x000018, 0x00001c ......

Но что показывают на моем экране:

0x000008, 0x000008, 0x00000c

0x000018, 0x000018, 0x00001c

0x000028, 0x000028, 0x00002c ......

Почему адрес памяти struct Thing Члены не выделены на то, что я ожидал? Адрес памяти между ptr имеет интервал 16 байтов, но не 8 байтов?

1 ответ

Решение

Большинство распределителей памяти не являются свободными - есть некоторое количество дополнительной памяти, используемой внутренне распределителем, предшествующим и / или следующим за каждым выделенным блоком.

В распределителе памяти вашей системы эти накладные расходы достигают восьми байт на выделенный блок. Это довольно типично для 32-битной системы; вероятно, он хранит размер выделенного блока (4 байта) и указатель на предыдущий блок (4 байта) или что-то подобное.

Еще один фактор, который нужно иметь в виду, состоит в том, что многие распределители имеют минимальный квант выделения, то есть "реальный" размер каждого выделенного блока округляется до ближайшего кратного стандартного размера. Это связано с тем, что определенные функции ЦП (особенно векторные операции) часто требуют выравнивания памяти по определенной границе, а также потому, что очень маленькие блоки неудобно отслеживать. В вашей системе квант, вероятно, составляет восемь байтов, поэтому в вашем примере это не входит в игру. (Вероятно, вы можете продемонстрировать этот эффект, изменив один из членов вашей структуры с int к char.)

Другие вопросы по тегам