DevGang
Авторизоваться

Понимание распределение Heap Memory в C — sbrk и brk

В этом уроке мы изучим память процесса, чтобы лучше понять, как память распределяется в heap в C. Для начала давайте взглянем на общую структуру памяти процесса.

Память стека

Когда вызывается функция, память стека увеличивается, чтобы вместить кадр стека функции. Когда функция завершает работу, размер стековой памяти уменьшается по мере того, как она выходит из стекового фрейма функции. Память стека начинается с верхнего края памяти и растет вниз, к heap.

Регистр специального назначения в вашем процессоре, называемый указателем стека, отслеживает текущую вершину стека. Каждый кадр стека содержит аргументы функции, локальные переменные и информацию о связи вызовов, например адреса возврата для функции. Поскольку функции можно вызывать внутри функций, мы часто можем видеть в стеке несколько кадров.

В C нам обычно не нужно слишком подробно беспокоиться о стековой памяти. Знание того, как работают функциональные фреймы, дает важный контекст, но обычно мы не взаимодействуем со стеком напрямую. Когда мы выделяем память в C, мы взаимодействуем с heap, которую мы рассмотрим далее.

Heap Memory

Heap — это динамическая область памяти, которая растет по направлению к стеку. Когда вы выделяете память в программе, эта память выделяется в heap. Для выделения памяти мы обычно используем malloc, основанный на другом наборе функций — brk() и sbrk(). Эти функции работают путем изменения размера разрыва программы, который представляет собой ячейку памяти, обозначающую конец heap и начало нераспределенной памяти.

brk и sbrk

Изменение размера кучи процесса — простая задача. Нам просто нужно указать ядру изменить местоположение остановки программы (которое определяется как текущая вершина кучи). Поскольку память, находящаяся после прерывания программы, является нераспределенной памятью, мы можем переместить разрыв в нераспределенную память, чтобы выделить некоторую новую память для нашего процесса. С этим процессом связаны две функции:

  • brk(void *end_data_segment): устанавливает прерывание программы в место, указанное в end_data_segment.
  • sbrk(intptr_t increment): увеличивает размер разрыва программы с шагом.

Чтобы увидеть, как работают эти функции, давайте рассмотрим простой пример.

#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[]){

    int *currentBreak = sbrk(0);
    printf("%p\n",currentBreak);

}

В этом примере укажите приращение 0 к sbrk. Когда для sbrk предоставляется приращение 0, возвращается текущий адрес прерывания.

Если вы укажете в sbrk значение, отличное от 0, вы получите адрес предыдущего разрыва, то есть адрес до того, как разрыв был изменен. Мы можем увидеть этот эффект, используя несколько приращений подряд.

#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[]){

    void *currentBreak = sbrk(0x5);
    printf("First increment of 0x5: %p\n",currentBreak);

    currentBreak = sbrk(0x5);
    printf("Second increment of 0x5: %p\n",currentBreak);

    currentBreak = sbrk(0x5);
    printf("Third increment of 0x5: %p\n",currentBreak);

    currentBreak = sbrk(0x5);
    printf("Fourth increment of 0x5: %p\n",currentBreak);

    currentBreak = sbrk(0x5);
    printf("Fifth increment of 0x5: %p\n",currentBreak);

}

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

Обратите внимание, что разрыв между первым и вторым приращением больше указанного нами 0x5. Это связано с тем, что printf выделяет память для использования в качестве буфера для стандартного вывода. Когда это происходит изначально, мы видим большие изменения в разрыве кучи. Третий, четвертый и пятый приращения последовательно перемещаются на приращение 0x5, поскольку между ними в куче не размещается никаких дополнительных данных.

В большинстве случаев мы не используем sbrk и brk напрямую для настройки кучи в C. Вместо этого мы используем более удобную для пользователя версию этого процесса, известную как malloc и free

Источник:

#Linux
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу