如果在libc中以库例程的形式实现malloc/free函数,那么它是基于sbrk系统调用还是mmap系统调用,还是其他什么方式实现的?
并且一般来说,sys/syscall.h中声明的函数是否包含目标机器上所有的系统调用?
如果在libc中以库例程的形式实现malloc/free函数,那么它是基于sbrk系统调用还是mmap系统调用,还是其他什么方式实现的?
并且一般来说,sys/syscall.h中声明的函数是否包含目标机器上所有的系统调用?
很多时候,malloc
和free
使用较低级别的虚拟内存分配服务,并一次性分配几个页面(甚至数兆字节),使用类似mmap和munmap(以及可能的sbrk)的系统调用。通常情况下,malloc
更喜欢在相关时重复使用先前free
的内存空间。大多数malloc
实现使用不同的策略来处理“大”和“小”的分配等等...
/proc/self/maps
用于您自己的进程或/proc/1234/maps
- 也可以使用pmap 1234
命令 - 用于pid为1234的进程)。malloc
实现的文章,选择一些其他的实现或者自己实现,并使用strace进行实验。<asm/unistd.h>
以获取系统调用列表。
malloc
(我相信这可能是最快的malloc
实现;但它并不是非常有用;它符合标准,例如n1570或更好)
我坚信C标准对于malloc
和free
非常模糊。我非常确定以下函数遵守标准的字面意思(但不是精神意义):
/* politically incorrect, but very probably standard conforming */
void *malloc (size_t sz) { if (sz>0) errno = ENOMEM; return NULL; }
void free(void*ptr) { }
当然,你需要相应地编写calloc
和realloc
的代码。
顺便提一下,每个使用malloc
的代码都应该针对其失败进行测试,但有些人-不正确地-没有这样做;malloc
在失败时可能返回NULL
,人们应该针对这种情况进行测试。
GNU libc提供了钩子以供您自己的malloc
函数使用(您甚至可以透明地通过它们使用Boehm's Garbage Collector)。这些钩子可能会被弃用并且不是标准的。
如果使用GNU libc,请还要查看mallinfo(3)和malloc_stat(3)及相关函数。
malloc
和 free
可以更简单,类似于 #define malloc(x) NULL
和 #define free(x) (void)1
:-) ISO 标准不要求设置 errno
,这是 POSIX 的一件事。您可能还想拦截 calloc
和 realloc
。 - paxdiablomalloc
可以只是一个宏吗?我认为它应该是一个函数(可分配给函数指针)。 - Basile Starynkevitchmalloc
和free
是标准C库函数,每个C实现都需要实现它们。
C标准只定义了这些函数的行为和预期行为,如何实现它们则由每个实现自行决定。
简而言之,它们是您使用的实现的实现细节。
(一个“实现”包括编译器、链接器、运行时库以及可能还有其他一些东西。)
malloc
和free
被实现为库函数,调用底层代码。如果操作系统提供的系统调用恰好符合C标准对malloc
和free
的要求,则它们可以作为系统调用实现。但是我不知道任何一个这样做的操作系统(即使是C语言的发源地Unix)。 - Keith Thompson