malloc/free是libc提供的系统调用还是库例程?

Pwn*_*Pwn 14 c linux libc system-calls

如果malloc/free是作为libc中的库例程实现的,那么它是在sbrk系统调用或mmap系统调用之上实现的,还是其他什么?

一般来说,sys/syscall.h中声明的函数是否包含目标机器中的所有系统调用?

Bas*_*tch 35

很多时候,mallocfree使用较低级别的虚拟内存分配服务和分配多个页面(或者甚至兆字节)一次,使用系统调用MMAPmunmap(也许SBRK).通常malloc更喜欢在相关时重用先前的 free存储空间.大多数malloc实现使用各种不同的策略进行"大"和"小"分配等...

请注意,虚拟地址空间可以受到限制,例如使用setrlimit(2).在Linux pmap(1)proc(5)上使用以了解有关某个进程的虚拟地址空间的更多信息(例如,/proc/self/maps对于您自己的进程或/proc/1234/maps- 也是pmap 1234命令 - 进行pid 1234的进程).

您可以查看您的GNU libc源代码,查看其他C标准库的源代码(例如musl-libc),阅读有关malloc实现,选择其他一些或实现您自己的,或使用strace来实验性地查找.

阅读系统调用手册页(即syscalls(2))和文件<asm/unistd.h>以获取系统调用列表.


非常快 malloc

(我相信这可能是最快的实现malloc;但它不是很有用;它符合标准)

我坚信,C标准大约是非常模糊mallocfree.我很确定以下功能是尊重标准的字母(但不是精神):

 /* politically incorrect, but very probably standard conforming */
 void *malloc (size_t sz) { if (sz>0) errno = ENOMEM; return NULL; }
 void free(void*ptr) { }
Run Code Online (Sandbox Code Playgroud)

当然你会编码callocrealloc相应地.

(BTW每个使用的代码malloc都应该测试它的失败,但有些 - 不正确 - 不会; 失败时malloc可以返回NULL,人们应该针对该情况进行测试)


GNU libc 为您自己的函数提供了钩子malloc(您甚至可以透明地使用Boehm的垃圾收集器).这些钩子可能会被弃用并且是非标准的.

如果使用GNU libc,还可以查看mallinfo(3)malloc_stat(3)以及相关函数.

  • 实际上,`malloc`和`free`可以更简单,比如`#define malloc(x)NULL`和`#define free(x)(void)1` :-) ISO不需要`errno`来设置,这是一个POSIX的事情.你可能也想拦截`calloc`和`realloc`. (4认同)
  • @paxdiablo:您确定`malloc`可以只是一个宏吗?我认为应该是一个函数(可分配给函数指针) (3认同)

Alo*_*ave 13

malloc并且free是由每个C实现实现的标准C库函数.

C标准仅定义了这些函数的行为方式以及它们所期望的行为.如何在每个实现中实现它们.

简而言之,它们是您使用的实现的实现细节.

("实现"包括编译器,链接器,运行时库以及其他一些东西.)

  • 最常见的是,`malloc`和`free`是作为调用低级代码的库函数实现的.如果操作系统碰巧提供的系统调用与C标准对"malloc"和"free"的行为完全匹配,那么它们可以实现为系统调用.但我不知道有没有这样做的操作系统(甚至是Unix,C的诞生地). (3认同)
  • @ kaizer.se:取决于,编译器可以使用平台提供的标准库实现,也可以提供自己的相同的实现。选择哪种取决于编译器。这就是*实施细节*的含义。 (2认同)