C(和C ++)包括一系列动态内存分配函数,其中大部分都是直观命名的,并且易于向具有基本内存理解的程序员解释。 malloc()
只是分配内存,而calloc()
分配一些内存并急切地清除它。还有realloc()
和free()
,这些都是不言自明的。
malloc()
的联构帮助页还提到了valloc()
,它分配了(size
)个字节与页面边框对齐。
不幸的是,我的背景在低级错综复杂方面不够彻底;分配和使用页面边界对齐的内存有什么影响,什么时候适合与常规malloc()
或calloc()
相对应?
答案 0 :(得分:13)
valloc
的联机帮助页包含一个重要说明:
函数valloc()出现在3.0BSD中。它被记录为在4.3BSD中已过时,在SUSv2中也是遗留的。它没有出现在POSIX.1-2001中。
valloc
已过时且非标准 - 要回答您的问题,在新代码中使用它永远不合适。
虽然有一些理由想要分配对齐的内存 - this question列出了一些好的内存 - 但通常最好让内存分配器找出给你的内存位。如果您确定需要将新分配的内存与某些内容对齐,请改用aligned_alloc
(C11)或posix_memalign
(POSIX)。
答案 1 :(得分:4)
页面对齐的分配通常不是为了提高速度 - 它们是因为您希望利用处理器MMU的某些功能,这通常适用于页面粒度。
一个例子是,如果您想使用mprotect(2)
来更改该内存的访问权限。例如,假设您要将一些数据存储在一块内存中,然后将其设置为只读,这样程序中任何试图写入的错误部分都会触发段错误。由于mprotect(2)
只能逐页更改权限(因为这是底层CPU硬件可以强制执行的),因此存储数据的块最好是页面对齐的,其大小最好是页面的倍数尺寸。否则,您设置为只读的区域可能包含仍需要写入的其他无关数据。
或许,您可能会在内存中生成一些可执行代码,然后想要稍后执行它。您默认分配的内存可能未设置为允许代码执行,因此您必须使用mprotect
为其授予执行权限。同样,这必须以页面粒度完成。
另一个例子是你现在想要分配内存,但是稍后可能想要mmap
之上的内容。
因此,一般来说,页面对齐内存的需求与某些相当低级别的应用程序有关,通常涉及某些特定于系统的内容。如果你需要它,你就会知道。 (如上所述,您不应该使用valloc
分配,而是使用posix_memalign
或匿名mmap
分配。)
答案 2 :(得分:-1)
首先valloc
已过时,应使用memalign
。
第二件事它根本不是C(C ++)标准的一部分。
这是一个与_SC_PAGESIZE
边界对齐的特殊分配。
何时使用它有用?我想永远不会,除非你有一些特定的低级要求。如果你需要它,你会知道需要它,因为它很少有用(可能只是在尝试一些微优化或在进程之间创建共享内存时)。
答案 3 :(得分:-1)
不言而喻的答案是,当malloc对于应用程序(虚拟)内存使用模式不适合(效率较低)并且valloc更适合(更高效)时,使用valloc是合适的。这将取决于操作系统和库以及架构和应用程序......
malloc传统上从释放的内存中分配实内存(如果可用),如果没有则增加brk点,在这种情况下,出于安全原因,它会被操作系统清除。
在一个哑实现中的calloc执行malloc然后(重新)清除内存,而智能实现将避免重新删除由操作系统自动清除的新分配的内存。valloc与虚拟内存有关。在使用文件系统的虚拟内存系统中,您可以分配大量内存或文件空间/交换空间,甚至超过物理内存,并且它将被页面交换,因此对齐是一个因素。在Unix中,创建指定文件的文件并添加/删除页面是使用inode来定义文件,但是在需要之前不处理实际的磁盘块,在这种情况下它会创建它们。因此,我希望valloc系统能够增加数据段交换的大小,而无需实际分配物理或交换页面,或运行for循环来清除所有内容 - 因为文件和分页系统会根据需要执行此操作。因此,valloc应该比malloc快得多。但与calloc一样,特殊的idiotsyncratic * x / C风格如何做到这一点取决于他们,而valloc手册页对这些期望完全没有帮助。
传统上这是用brk / sbrk实现的。当然,在虚拟内存系统中,无论是分页系统还是分段系统,都不需要任何这样的brk / sbrk内容,只需简单地在文件或地址空间中写入最后一个位置就可以扩展到点。
重新分配到页面边界,这通常不是用户想要或需要的东西,而是通常是系统想要或需要的东西。
模拟valloc的一种(可能更昂贵的)方法是确定页面边界,然后使用此对齐规范调用aligned_alloc或posix_memalign。
valloc已被弃用或已被删除或在某些操作系统中不需要这一事实并不意味着它不是仍然有用并且需要在其他操作系统中获得最佳效率。如果它已经被弃用或删除,人们会希望有更高效的替换(但我不会赌它,并且可能,确实有,写了我自己的malloc替换)。
在过去40年中,真实和(曾经发明的)虚拟内存的权衡已经周期性地发生变化,主流操作系统倾向于追求褶边而不是效率,程序员没有(时间或空间)效率一个主要的当务之急。在嵌入式系统中,效率更为关键,但即使标准操作系统和/或工具通常也不能很好地支持效率。但是,如果有疑问,您可以为您的应用程序推送自己的malloc替换,以满足您的需求,而不是依赖于其他人醒来并决定执行/实现,或撤消/弃用。
所以真正的答案是你不一定要使用valloc或malloc或calloc或你当前的操作系统颠覆所提供的任何替换。