Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么malloc和sbrk从不同的段返回地址?_C_Malloc_Sbrk - Fatal编程技术网

为什么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()
的内存在位置上有较大差异的原因是glibc
malloc()
实现在内部使用
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阈值的内存,glibc
malloc()
实现将内存分配为私有匿名映射 使用
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