Использование памяти программы C – больше памяти, чем выделено

У меня есть следующий код:

int main() { char * str1 = (char*)malloc(101 * sizeof(char)); for (int i=0; i<100; i++) { str1[i] = 'b'; } str1[100] = 0; char * str2 = (char*)malloc(1001 * sizeof(char)); for (int i=0; i<1000; i++) { str2[i] = 'a'; } str2[1000] = 0; for (int i=0; i<7000; i++) { char * tmp = str2; str2 = (char*) malloc((strlen(str2) + strlen(str1) + 1) * sizeof(char)); sprintf(str2, "%s%s", tmp, str1); free(tmp); } free(str1); free(str2); } 

При его запуске диспетчер задач сообщает следующее использование памяти: начало программы – 1056 КБ, конец программы – 17 748 КБ

Насколько мне известно, утечек памяти нет, и я скомпилировал ее без символов отладки (режим выпуска).

Любые идеи, почему это может произойти?

Я думаю, это потому, что free не нужно возвращать память в ОС. Он просто возвращает его в свободный пул, откуда он может быть выделен malloc .

Это, вероятно, артефакт того, как malloc выбирает из доступных пулов памяти, чтобы удовлетворить malloc. Кроме того, такие инструменты, как TaskManager и top (для unix), как правило, плохо отображают фактическую память, используемую процессом. Каждый раз, когда один из моих клиентов дает мне лучший результат и говорит, что мой процесс протекает, я сжимаю, потому что теперь мне нужно доказать, что это не так.

malloc – это функция управления памятью, предоставляемая стандартной библиотекой C. Когда ваша программа вызывает malloc, она напрямую не выделяет память из операционной системы. Реализации Malloc обычно имеют пул памяти, который они разбивают на блоки для удовлетворения запросов на распределение. Когда вы звоните бесплатно, вы возвращаете свой блок памяти обратно в этот пул памяти.

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

Диспетчер задач в Windows или выше в linux сообщит объем памяти, который операционная система выделила вашему процессу. Обычно это будет больше, чем объем памяти, которую ваша программа выделила через malloc.

Если вы используете программу linux, вы можете увидеть, как эти вызовы malloc и brk выполняются

 ltrace -S  malloc(65536  SYS_brk(NULL) = 0x2584000 SYS_brk(0x25b5000) = 0x25b5000 SYS_brk(NULL) = 0x25b5000 <... malloc resumed> ) = 0x2584010 

В этом примере мы пытаемся malloc (65536), но система malloc не имеет достаточной свободной памяти для удовлетворения этого запроса. Поэтому он вызывает системный вызов brk (), чтобы получить больше памяти от операционной системы. По завершении этого вызова он может возобновить вызов malloc и предоставить программе запрошенную память.