malloc () - использует ли он brk () или mmap()

код C:

// program break mechanism
// TLPI exercise 7-1

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

void program_break_test() {
    printf("%10pn", sbrk(0));

    char *bl = malloc(1024 * 1024);
    printf("%xn", sbrk(0));

    free(bl);
    printf("%xn", sbrk(0));

}

int main(int argc, char **argv) {
    program_break_test();
    return 0;
}

при компиляции следующего кода:

 printf("%10pn", sbrk(0));

я получаю предупреждающий совет:

format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int’

Вопрос 1: почему это?


и после malloc(1024 * 1024), похоже, перерыв программы не изменился.

вот вывод:

9b12000
9b12000
9b12000

Вопрос 2: процесс выделения памяти на куче, когда начнется впрок? Или компилятор изменить точку времени для выделения? Иначе зачем?


[update] сводка: brk () или mmap()

после просмотра TLPI и проверки man-страницы (с помощью автора TLPI), теперь я понимаю, как malloc() решите использовать brk() или mmap(), следующим образом:

mallopt() можно задать параметры для управления поведением malloc() и там есть параметр с именем M_MMAP_THRESHOLD в общем:

  • если запрошенная память меньше чем это,brk() будут использованы;
  • если запрашиваемая память больше или равна ей,mmap() будут использованы;

значение параметра по умолчанию составляет 128kb (в моей системе), но в моей программе тестирования я использовал 1Mb, поэтому mmap() был выбран, когда я изменил запрошенную память на 32kb, я увидел brk() будут использованы.

подробная информация параметр можно найти в MAN-странице mallopt().

3 ответов


если мы изменим программу, чтобы увидеть, где malloc'д память:

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

void program_break_test() {
  printf("%10p\n", sbrk(0));

  char *bl = malloc(1024 * 1024);
  printf("%10p\n", sbrk(0));
  printf("malloc'd at: %10p\n", bl);

  free(bl);
  printf("%10p\n", sbrk(0));

}

int main(int argc, char **argv) {
  program_break_test();
  return 0;
}

это, возможно, немного яснее, что sbrk не изменится. Память, данная нам malloc отображается в совершенно другое место.

вы также можете использовать strace в Linux, чтобы узнать, какие системные вызовы выполняются, и узнать, что malloc С помощью mmap выполнить выделение.


malloc не ограничивается использованием sbrk для выделения памяти. Например, он может использовать mmap для отображения большой MAP_ANONYMOUS блока памяти; обычно mmap назначит виртуальный адрес далеко от сегмента данных.

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


формат "%p "ожидает аргумент типа" void *", но аргумент 2 имеет тип "int"

ответ на вопрос 1: компилятор говорит вам, что аргумент должен быть void *, но вы предоставляете int вместо. Это должно быть очевидно, если ты потратишь пять секунд на чтение и понимание ошибки. Есть что-то, чего ты не понимаешь? Если это так, задайте более подробный вопрос о том, что вас смущает, а не "почему это?"...

аналогичное предупреждение должно произойти для printf("%x\n", sbrk(0)); Как сообщает руководство, %x, как ожидается, будет соответствовать