他们的巨大优势,即插入O(1),在碎片化内存的环境中看起来相当无用,并且数千次调用内存分配器给我们另外10个字节。
编辑澄清:
在接受采访时询问了这个问题。这不是一个工作场所的问题,所以通常的启发式方法是希望盲目地从一小组标准算法中找出正确的决策而不适用。
现有的答案和评论提到“malloc不是那么慢”,“malloc部分地对抗碎片化”。好吧,如果我们使用另一种数据结构,例如C ++向量的C端口(即 - 分配足够大小的顺序内存,如果数据扩展,重新分配到两倍大的块),所有问题都解决了,但我们放松了快速插入/删除。链接列表(分配在哪里?)的任何场景都具有广泛的向量优势?
答案 0 :(得分:7)
这听起来像是过早优化。我认为正确的方法是:
答案 1 :(得分:4)
如果您担心标准分配器无法有效处理专用的10字节分配,请编写一个自定义分配器,从标准(malloc()
)分配器中获取大块内存,并有效地分发小项目。当你在最初的大块中耗尽内存时,你应该不重新分配;你应该分配一个新的(额外的)大块并从中分配。您可以决定如何处理释放的内存。您可以简单地忽略版本,直到您在使用列表处理结束时释放所有大块。或者你可以通过跟踪大块的释放内存来使生活复杂化。这样可以减少整体内存使用量,但最初编写起来会更复杂。
另一方面,您应该意识到过早优化的风险。你有没有测量过性能?鉴于我在你最近的问题中所看到的,你应该坚持使用malloc()
而不是尝试编写自己的分配器(
答案 2 :(得分:0)
这可能不是确切的解决方案,而是另一种方法
然而,这说起来容易做起来难。你可能会遇到很多问题。
因此,建议对malloc
和相关函数进行此类优化。
从堆栈分配不是一个可行的选择。您无法从堆栈中malloc
。您将不得不在某些功能中预先分配大块缓冲区。在这种情况下,数组比链表更好。
答案 3 :(得分:0)
理想情况下,您的链接列表实现不应使用上述任何一种。应该由调用者来分配和销毁内存。考虑像sprintf
,fgets
等函数......他们分配任何内存吗?不,这是有原因的:简单。想象一下,如果你必须free
从fgets
获得的所有内容(或更糟糕的是,fscanf
)。难道不痛苦吗?尝试开发您的功能以与标准库保持一致。
声明listnode_alloc
函数可能会有所帮助,但这只会包含malloc
和listnode_init
函数。考虑realloc
如何处理NULL
输入...
答案 4 :(得分:0)
好吧,内存分配策略可能会因内存碎片,成千上万的系统调用等而有所不同,这就是使用O的原因! ; - )