为什么malloc和sbrk从不同的段返回地址?
我试图理解动态内存分配是如何发生的。因此,我考虑使用为什么malloc和sbrk从不同的段返回地址?,c,malloc,sbrk,C,Malloc,Sbrk,我试图理解动态内存分配是如何发生的。因此,我考虑使用sbrk()系统调用实现自己的malloc。 我这里的问题是,当我尝试分配动态内存时,sbrk()和malloc()返回不同的地址,但不是连续的 这是我的密码 #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdlib.h> int main(int ar
sbrk()
系统调用实现自己的malloc。
我这里的问题是,当我尝试分配动态内存时,sbrk()和malloc()返回不同的地址,但不是连续的
这是我的密码
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
printf("\nsbrk(0) %llu ",(unsigned long long)sbrk(0));
printf("\nmalloc(8) %llu ",(unsigned long long)malloc(8));
printf("\nmalloc(8) %llu ",(unsigned long long)malloc(8));
printf("\nsbrk(8) %llu ",(unsigned long long)sbrk(8));
printf("\nmalloc(8) %llu ",(unsigned long long)malloc(8));
printf("\nmalloc(8) %llu ",(unsigned long long)malloc(8));
printf("\n");
return 0;
}
有人能解释为什么sbrk(8)不是连续的位置。该标准不能保证存储的连续性,即使是连续调用
malloc
分配的内存。因此,在代码中对malloc
的不同调用不需要产生连续的位置
C11标准规定:
连续调用所分配的存储的顺序和连续性
aligned\u alloc
、calloc
、malloc
和realloc
函数未指定
由于混合使用
malloc
和sbrk
调用而产生的地址也不必是连续的。假设您在Linux上运行,malloc()
和sbrk()
的内存在位置上有较大差异的原因是glibcmalloc()
实现在内部使用sbrk()
来获取函数(如malloc()
返回给调用者)的内存。例如,假设初始内部glibc实现通过sbrk()
获得32mb堆内存,从malloc()
返回的内存将在这个32mb块中。如果然后使用sbrk()
获取内存,它将来自原始32 MB块末尾新分配的内存,因此malloc()
和sbrk()
的地址将不同
请注意,您不能安全地混合使用malloc()
(和calloc()
,realloc()
等)和sbrk()
,因为malloc()
的内部实现使用sbrk()
来获取通过malloc()
返回的内存。Per:
通常,malloc()
从堆中分配内存,并调整
使用sbrk(2)
根据需要调整堆的大小。分配块时
对于大于MMAP\u阈值的内存,glibcmalloc()
实现将内存分配为私有匿名映射
使用mmap(2)
<代码>MMAP_阈值默认为128 kB,但为
可使用mallopt(3)
进行调节。Linux 4.7之前的配置
使用mmap(2)
执行,不受RLIMIT_数据
资源的影响
限制;自Linux4.7以来,此限制也适用于分配
使用mmap(2)
执行
在Linux上混合使用malloc()
和sbrk()
来获取内存时,可能会损坏进程的堆。现代POSIX分配器通常用于分配,而不是sbrk
。顺便说一句,打印指针(void*
)的正确格式是%p
。
sbrk(0) 30306304
malloc(8) 30306320
malloc(8) 30306352
sbrk(8) 30441472
malloc(8) 30306384
malloc(8) 30306416