Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.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
calloc与malloc+完全相同吗;记忆集?_C_Linux_Linux Kernel_Glibc - Fatal编程技术网

calloc与malloc+完全相同吗;记忆集?

calloc与malloc+完全相同吗;记忆集?,c,linux,linux-kernel,glibc,C,Linux,Linux Kernel,Glibc,在linux中,calloc与malloc+memset完全相同,还是取决于linux/内核的确切版本 我特别感兴趣的问题是,你是否可以调用比你实际拥有的更多的RAM(因为你当然可以调用比你实际拥有的更多的RAM,你只是不能写入它)。换句话说,calloc是否总是按照规范的建议写入分配给您的内存。您不能malloc(3)比执行malloc(3)-ing的进程提供的内存更多malloc(3)如果无法分配要分配的内存量,则返回NULL。此外,malloc(3)和memset(3)是由c库(libc.

在linux中,calloc与malloc+memset完全相同,还是取决于linux/内核的确切版本


我特别感兴趣的问题是,你是否可以调用比你实际拥有的更多的RAM(因为你当然可以调用比你实际拥有的更多的RAM,你只是不能写入它)。换句话说,calloc是否总是按照规范的建议写入分配给您的内存。

您不能
malloc(3)
比执行
malloc(3)
-ing的进程提供的内存更多
malloc(3)
如果无法分配要分配的内存量,则返回NULL。此外,
malloc(3)
memset(3)
是由c库(
libc.so
)定义的,而不是由内核定义的。Linux内核定义了
mmap(2)
和其他低级内存分配函数,而不是
*alloc(3)
系列(不包括
kalloc()
)。

你不能
malloc(3)
比内核给进程的
malloc(3)
内存更多
malloc(3)
如果无法分配要分配的内存量,则返回NULL。此外,
malloc(3)
memset(3)
是由c库(
libc.so
)定义的,而不是由内核定义的。Linux内核定义了
mmap(2)
和其他低级内存分配函数,而不是
*alloc(3)
系列(不包括
kalloc()
)。

当然,这取决于实现,但在现代Linux上,您可能可以。最简单的方法是尝试一下,但我是基于以下逻辑说的

您可以
malloc
超过您拥有的内存(物理+虚拟),因为内核会延迟内存的分配,直到您实际使用它。我相信这会增加你的程序不因内存限制而失败的几率,但这不是问题所在

calloc
malloc
相同,但零初始化内存。当您向Linux请求一页内存时,Linux已经将其初始化为零。因此,如果
calloc
可以判断出它请求的内存是从内核请求的,那么它实际上不必为零初始化它!因为它没有,所以无法访问该内存,因此它应该能够请求比实际内存更多的内存


正如评论中提到的,这提供了一个很好的解释。

当然,这取决于实现,但在现代Linux上,您可能可以。最简单的方法是尝试一下,但我是基于以下逻辑说的

您可以
malloc
超过您拥有的内存(物理+虚拟),因为内核会延迟内存的分配,直到您实际使用它。我相信这会增加你的程序不因内存限制而失败的几率,但这不是问题所在

calloc
malloc
相同,但零初始化内存。当您向Linux请求一页内存时,Linux已经将其初始化为零。因此,如果
calloc
可以判断出它请求的内存是从内核请求的,那么它实际上不必为零初始化它!因为它没有,所以无法访问该内存,因此它应该能够请求比实际内存更多的内存


如注释中所述,这提供了一个很好的解释。

是否需要将
calloc
写入内存取决于它是从已经分配给进程的堆页获得分配,还是必须请求内核为进程分配更多内存(使用系统调用,如
sbrk()
mmap()
)。当内核向进程分配新内存时,它总是首先将其归零(通常使用VM优化,因此它实际上不必写入页面)。但是,如果它正在重用以前分配的内存,它必须使用
memset()
将其归零。

是否需要将
calloc
写入内存取决于它是从已经分配给进程的堆页获得分配,还是必须请求内核为进程分配更多内存(使用系统调用,如
sbrk()
mmap()
)。当内核为进程分配新内存时,它总是首先将其归零(通常使用VM优化,因此它实际上不必写入页面)。但如果它在重用以前分配的内存,则必须使用
memset()
将其归零。

在或中没有提到。Linux使用虚拟内存,可以分配更多系统中物理可用的内存。一个简单的
calloc()
实现,只需在用户空间中执行
malloc()
加上
memset()
,即可触及每一页

由于Linux通常以4k块进行分配,因此所有
calloc()
块都相同,并且最初读取为零。也就是说,相同的4k内存块可以映射为只读和整个
calloc()
仅占用大约
size/4k*指针大小+4k
的空间。当程序写入
calloc()
空间时,会发生页面错误,Linux将分配一个新页面(4k)并恢复程序

这称为或COW
malloc()
通常会以相同的方式运行。对于较小的大小,将使用binning并与其他较小大小的分配共享4k页面

因此,通常涉及两层

  • Linux内核的进程内存管理
  • glibc堆管理
  • 如果请求的内存很大,并且需要为进程分配新内存,那么上述大部分都适用(通过Linux的进程内存管理)。但是,如果请求的内存很小,那么它就像一个