Системные вызовы malloc и free

Для работы вычислительного процесса, начиная с самого первого отведенного ему такта процессорного времени, нужна оперативная память.

Загрузчик операционной системы еще до запуска процесса (программы) на исполнение размещает в выделенной системой памяти страницы сегментов CODE, DATA и STACK. Размеры этих сегментов во время работы процесса не изменяются.

Вычислительный процесс может явным образом попросить у операционной системы дополнительную память.

Выделенная память называется сегментом "куча" или HEAP. Его размер динамически меняется во время исполнения программы, поэтому такая память называется динамической.

Диалог между ОС и процессом по поводу памяти происходит через системные вызовы malloc() и free():

void *malloc(size_t size); //функция выделения памяти

void free(void *ptr); //функция освобождения памяти

Здесь size_t – размер выделяемой области памяти в байтах; void* - обобщенный тип указателя, т.е. не привязанный к какому-либо конкретному типу.

Если выделение не произошло (то есть ОС отказала программе в выдаче дополнительной динамической памяти), malloc() возвращает значение адреса NULL.

Пример работы функций malloc() и free()

#include <stdlib.h>
#include <stdio.h>

int main()
{
    double *pd = (double *)malloc(10 * sizeof(double));
    if(pd != NULL)
    {
        //адресная арифметика обеспечит перебор адресов
        // от pd до pd + 9*sizeof(double) включительно
        for(double *p = pd; p < pd + 10; p++)
            *p = 0.0; //зануляем ячейку памяти типа double
    } else {
        printf(“Не удалось выделить память.”);
    }
    free(pd);
    return 0;
}

Заметим, что у десяти ячеек памяти, которые мы использовали как ячейки типа double, вообще не существует собственных имен, работа с ними возможна только по адресу, хранящемуся в каком-либо указателе.

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