在linux中,calloc与malloc + memset完全相同,还是取决于确切的linux /内核版本?
我特别感兴趣的是你是否可以使用比实际更多的内存来调用RAM(因为你可以使用更多RAM来实现内存,你只能写入它)。换句话说,calloc总是实际上写入你已经分配的内存,因为规范建议应该这样做。
答案 0 :(得分:5)
当然,这取决于实现,但在现代Linux上,你可能会。最简单的方法是尝试它,但我基于以下逻辑说这个。
你可以malloc
超过你拥有的内存(物理+虚拟),因为内核会延迟你的内存分配,直到你真正使用它为止。我相信,为了增加你的程序因内存限制而失败的机会,但这不是问题。
calloc
与malloc
相同,但零会初始化内存。当您向Linux请求内存页面时,Linux已将其初始化为零。因此,如果calloc
可以告诉它所要求的内存只是从内核请求的,那么它实际上不必将其初始化为零!由于它没有,因此无法访问该内存,因此它应该能够请求比实际更多的内存。
正如评论中提到的this answer提供了一个非常好的解释。
答案 1 :(得分:2)
calloc
是否需要写入内存取决于它是否从已分配给进程的堆页中获得分配,还是必须请求内核将更多内存分配给进程(使用系统调用,例如sbrk()
或mmap()
)。当内核为进程分配新内存时,它总是先将其归零(通常使用VM优化,因此实际上不必写入页面)。但如果它重用之前分配的内存,则必须使用memset()
将其归零。
答案 2 :(得分:1)
cited duplicate或此处未提及。 Linux使用虚拟内存,可以分配更多系统中物理可用的内存。只需在用户空间中执行calloc()
加malloc()
的{{1}}的简单实现即可触及每个页面。
由于Linux通常以4k块的形式分配,所有memset()
块都是相同的,最初读为零。也就是说,相同的4k内存块可以映射只读,整个calloc()
空间只能占用大约calloc()
。当程序写入size/4k * pointer_size + 4k
空间时,会发生页面错误,Linux将分配一个新页面(4k)并恢复该程序。
这简称为copy-on-write或 COW 。 calloc()
通常会以相同的方式行事。对于小尺寸,the 'C' library将使用 binning 并与其他小尺寸分配共享4k页。
因此,通常涉及两个层次。
如果请求的内存大小很大并且需要为进程分配新的内存,那么上述大部分内容都适用(通过Linux的进程内存管理)。但是,如果请求的内存很小,那么它就像malloc()
加malloc()
。在大的分配大小中,memset()
在触及内存时会受到破坏,内核认为需要分配新页面。
答案 3 :(得分:0)
你不能malloc(3)
ram比内核给你的进程malloc(3)
更多。如果无法分配要分配的内存量,则malloc(3)
将返回NULL。此外,malloc(3)
和memset(3)
由您的c库(libc.so
)定义,而不是您的内核。 Linux内核定义mmap(2)
和其他低级内存分配函数,而不是*alloc(3)
系列(不包括kalloc()
)。