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, как ожидается, будет соответствовать