仅在缓冲区可以扩展的情况下才调整缓冲区大小的内存分配?

时间:2018-11-06 07:02:07

标签: c malloc realloc

阅读realloc()的手册页后,我意识到它的工作方式与我认为的有所不同。我本来以为realloc()会尝试调整以前用malloc-family函数之一分配的缓冲区的大小,如果它不能就位扩展 缓冲区,那么它将失败。但是,手册页指出:

  

realloc()函数返回一个指向新分配的内存的指针,该指针适合于任何内置类型,并且可能与ptr不同,如果请求失败,则为NULL。

我要说的是“可能与ptr不同”


基本上,我想要的是一个类似于realloc()的函数,但是如果不能就地扩展缓冲区 ,该函数将失败。在标准C库中似乎没有函数可以执行此操作;但是,我假设可能有一些特定于OS的功能可以完成相同的功能。

有人可以告诉我那里有哪些功能可以执行我上面描述的操作,以及它们特定于哪个OS?最好是,我至少想知道特定于Linux和Windows的功能(Mac OS也是一个不错的选择:))。


这可能是this post的副本,但我认为并非出于以下原因:

  1. 我链接到的帖子中的问题只是问:是否存在一个扩展缓冲区的函数,而我问的是哪个函数会在适当的位置扩展缓冲区。

  2. 该帖子的可接受答案不包含我需要的信息。


编辑

有些人想知道我需要的用例是什么,所以我将在下面进行解释:


我正在编写C预处理器(是的,我知道...不要重新发明轮子...好吧,无论如何我都在做,所以在那里)。 C预处理器的一个组件是一个高速缓存,用于存储来自各种源文件的pp令牌,其中每个源文件的pp令牌集都可以在高速缓存中分段。缓存本身是大块内存的链接列表。理想情况下,我想使此链接列表简短,因此为什么要首先尝试调整缓冲区的大小(就地);但是,如果无法进行适当的大小调整,那么我只想向链接列表添加另一个节点(即内存块)。

在每个缓存缓冲区中,还有其他的链表节点,这些节点提供了一种遍历每个单独源文件的所有pp令牌的方法,这些令牌可能会分散在组成缓存的各个缓存缓冲区中。 / p>


我需要前面讨论的那种内存重新分配的原因如下:

  1. 如果无法适当调整高速缓存缓冲区的大小,并且必须分配新的缓冲区并复制旧的内存内容,那么我将有很多悬空指针。 Jonathan Leffler建议我将偏移量而不是指针存储在缓冲区中,而不是甚至没有想到的指针,这是一个好主意!但是,原因2 ...

  2. 我希望高速缓存的实现尽可能快,并且,如果我错了,请更正我,但是在我看来,(对于我的用例)它平均速度更快如果无法适当调整给定的缓存缓冲区大小,只需将新的缓存缓冲区添加到链接列表中,而不是分配新的缓冲区并复制所有先前的内容并释放旧的缓冲区。附带说明,我计划在每次需要调整缓存大小时将分配的缓存缓冲区的大小加倍。

1 个答案:

答案 0 :(得分:0)

内存管理(以malloc和朋友的形式)通常以库的形式实现;它不是操作系统的一部分。 (该库的实现可能需要使用一些OS设施来获取原始内存-尽管这不是给定的-但不需要让OS来分配和释放单个分配。)因此,您无需做任何事情。找到“特定于操作系统”的解决方案。

有许多不同的内存分配库可用。如果您决定使用特定发行版中预装的替代软件,则可能还希望安排标准库也使用它。具体操作方法各不相同。

大多数分配库的确包含一些其他接口,但是我不知道有哪个库可以提供您想要的功能。更为常见的是一种API,用于找出分配中实际上有多少内存(通常比malloc请求的内存更多)。对于许多库来说,realloc仅在已经足够大的情况下才会扩展分配,但是可能有些库愿意合并后面的空闲块以使非复制realloc成为可能

dynamic memory allocation上的Wikipedia页面上列出了一些常用的库,并且对实现技术也有很好的概述。

当然,您总是可以编写自己的内存管理器(或修改开源库)来实现该功能。但是,尽管这将是一个有趣且令人满意的项目,但我强烈建议您考虑(并研究)在公共内存管理库中未实现这种看似简单的想法的原因。有充分的理由。