简单的 c malloc
Posted
技术标签:
【中文标题】简单的 c malloc【英文标题】:simple c malloc 【发布时间】:2011-04-14 17:38:08 【问题描述】:虽然对于 C/C++,malloc
/ free
有许多不同的复杂实现,但我正在寻找一个非常简单且(特别是)小的,适用于固定大小的缓冲区并支持 @987654323 @。不需要线程安全等,我的对象很小,大小变化不大。有什么可以推荐的实现吗?
编辑:
我将使用该实现作为接收器的通信缓冲区来传输可变大小的对象(接收器不知道)。分配的对象不会存活很久,但可能有多个对象同时使用。
由于每个人似乎都推荐标准 malloc,我或许应该重新提出我的问题。我需要的是在缓冲区之上“最简单”的 malloc 实现,我可以开始针对自己的需要进行优化。也许最初的问题不清楚,因为我不是在寻找优化的 malloc,只是为了一个简单的。我不想从 glibc-malloc 开始并对其进行扩展,而是使用轻量级的。
【问题讨论】:
你能澄清一下“支持realloc
”是什么意思吗? realloc
的一种兼容实现仅使用 malloc
、free
和 memcpy
。你能接受吗?从技术上讲,另一个兼容的实现总是返回 NULL,但很明显你不是那个意思。
你需要解释为什么你不能使用你的编译器自带的。如果这是因为您在某种环境中工作,而您的编译器没有附带malloc
(可能是嵌入式软件),那么您需要描述环境以获取任何对您有用的答案。目前,这个问题还不能令人满意地回答(除了 Martin York 建议使用与编译器捆绑的那个)。
是的,一个非常简单的realloc
(如果缓冲区中有足够的可用空间则不返回NULL)是可以接受的。
对 realloc 的支持似乎与在固定大小的缓冲区上工作不一致——你的意思是“在可用内存的固定子集中工作”还是“与固定大小的对象一起工作”——或其他什么?
我的意思是:malloc 等在我提供的可用内存的固定子集上工作。
【参考方案1】:
我推荐与编译器捆绑在一起的标准库。
还应注意,重新定义 malloc/free 没有合法的方法
【讨论】:
如果有的话,有一些差异的小对象是默认分配器的理想选择。 这可能没问题(我目前正在使用它),但我想知道一个非常简单且受限制的实现是否可以为我的应用程序提供一些加速。 @Thomas:一切皆有可能。但是其他实现旨在解决实现者遇到的特定问题。除非您与他们具有完全相同的特征,否则它不太可能有所帮助。 @Thomas:很可能你的 C 库附带的 malloc 版本已经经过多年精心优化,以尽可能快地用于最常见的使用配置文件。您可能会发现它已经足够快了。 我绝对不否认标准实现是可以的 - 我只是想看看不同之处,我无法在google/sf 给了我很多。【参考方案2】:编译器附带的malloc
/free
/realloc
几乎肯定比您要插入的某些函数更好。
可以对固定大小的对象进行改进,但这通常不涉及尝试替换malloc
,而是用memory pools 对其进行补充。通常,您会使用malloc
来获取大块内存,您可以将其划分为适当大小的离散块,并管理这些块。
【讨论】:
【参考方案3】:呼应建议首先衡量,并且仅在性能不佳时才进行专门化 - 应该很容易抽象您的 malloc/free/realloc,这样替换就很简单了。
鉴于专用平台,我无法评论运行时的有效性。如果您确实调查了自己的对象池(请参阅其他答案)或小对象分配 Loki 或 this 值得一看。第二个链接也有一些关于这个问题的有趣评论。
【讨论】:
第二个链接(“micro-allocator”)看起来不错,但它仍然有太多功能:线程支持,不同块大小的不同处理等 - 我真的不需要所有这些。我正在考虑大约 100 到 200 行代码,这些代码只做基础的,仅此而已,但稳定且经过测试。 这是否适用于您的场景,因为您似乎正在以 FIFO 方式处理传入数据?小而完美的 :-) boost.org/doc/libs/1_44_0/libs/circular_buffer/doc/… 是的 - 我已经开始编写一个简单的 malloc 并为此使用了一个循环缓冲区,但我意识到一个空闲块列表是不够的,而不是考虑使用两个列出或将我的“标题”结构扩展到分配的块,我认为最好从现有的 malloc 实现开始。 我怀疑你发现的任何东西都会是 > 你想要的 LoC 大小。另外,您的最终结果将是。【参考方案4】:听起来你正在寻找一个内存池。 Apache Runtime library 有一个不错的,它也是跨平台的。
它可能不是完全轻量级的,但源是开放的,你可以修改它。
【讨论】:
是的,apr_pools.c 中的 2601 行代码并不完全是轻量级的。也许我真的应该花一个小时来编写我自己的小实现。我只是在想,也许很多人已经写了这样一个基本的 malloc,所以我可以重用和扩展它。【参考方案5】:Kerninghan 和 Ritchie 似乎在他们的 C 书中提供了一个小的 malloc / free - 这正是我正在寻找的 (reimplementation found here)。我只会添加一个简单的 realloc。
对于其他与此一样简单和简洁的实现(例如,使用双向链表)的建议,我仍然很高兴。
【讨论】:
@Ben:OP 回答了他自己的问题。 :-)【参考方案6】:我通常不会用分配函数重新发明***除非我的内存使用模式也不被 malloc/etc 支持。 或内存可以划分为一个或多个预先分配的区域,每个区域包含一个或两个 LIFO 堆(释放任何对象会释放同一堆中在其之后分配的所有对象)。在后一种情况的常见版本中,只有释放任何东西时,所有东西都会被释放;在这种情况下,malloc() 可以有效地重写为:
字符 *malloc_ptr; 无效 *malloc(int 大小) 无效 *ret; ret = (void*)malloc_ptr; malloc_ptr += 大小; 返回 ret;每个分配对象的零字节开销。在 malloc() 不足的场景中使用自定义内存管理器的场景示例是可变长度测试记录生成可变长度结果记录(可能更长或更短)的应用程序;该应用程序需要支持获取结果并在批处理中添加更多测试。测试存储在从缓冲区底部开始的递增地址,而结果存储在从顶部开始的递减地址。作为一项后台任务,当前测试之后的测试将被复制到缓冲区的开头(因为只有一个指针用于读取测试以进行处理,所以复制逻辑将根据需要更新该指针)。如果应用程序使用了 malloc/free,则测试和结果的交错分配可能会产生内存碎片,但使用所使用的系统则没有这种风险。
【讨论】:
【参考方案7】:CCAN中有一个比较简单的内存池实现:
http://ccodearchive.net/info/antithread/alloc.html
这看起来符合您的要求。当然,alloc.c 是 1230 行,但其中很大一部分是测试代码和列表操作。它比你实现的代码复杂一点,但体面的内存分配很复杂。
【讨论】:
@AmigableClarkKant:谢谢,已修复以上是关于简单的 c malloc的主要内容,如果未能解决你的问题,请参考以下文章