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