Malloc, как правило, довольно недорогой. Это только дорого, если он генерирует системный вызов, чтобы получить больше места в куче. Например, в UNIX-подобных системах в конечном итоге будет сгенерирован вызов sbrk, который будет дорогим. Если вы постоянно используете malloc и освобождаете один и тот же объем памяти, это быстро сойдет с ума. Например, рассмотрим следующую небольшую тестовую программу:
#include <stdlib.h>
int main()
{
int i=0;
int *ptr;
for(int i=0; i<1e6; i++) {
ptr = malloc(1024*sizeof(int));
free(ptr);
}
}
Он выделяет 1024 целых числа и освобождает их и делает это миллион раз. Запустив это на моей довольно скромной машине Linux, превращенной в Linux, я получаю время, которое выглядит так:
time ./test
real 0m0.125s
user 0m0.122s
sys 0m0.003s
Теперь, если я закомментирую malloc и свободную часть цикла, я получу следующее время:
time ./test
real 0m0.009s
user 0m0.005s
sys 0m0.005s
Итак, вы видите, что у malloc и free есть накладные расходы, хотя я думаю, что превышение накладных расходов на бездействие более чем в десять раз ужасно много накладных расходов.
Это особенно быстро, если он может просто продолжать многократно использовать один и тот же кусок кучи (как здесь). Конечно, если бы я продолжал многократно выделять и расширять программу, это заняло бы больше времени, потому что это привело бы к нескольким системным вызовам.
Конечно, ваш пробег может варьироваться в зависимости от ОС, компилятора и реализации stdlib.