C++ 为什么malloc()基于链表?
在最坏的情况下,在大小为C++ 为什么malloc()基于链表?,c++,c,memory,memory-management,data-structures,C++,C,Memory,Memory Management,Data Structures,在最坏的情况下,在大小为n的内存段(这是正确的术语吗?)上,链表需要O(n)时间来分配大小合适的内存块 然而,如果malloc是基于树的,例如,一个间隔树,则只需要O(logn)时间。此外,树可以在没有额外时间的情况下(就时间复杂度而言)满足这样的要求,例如“找到最小的可用内存块,其大小大于它们”x“”、“始终在可用内存的边界上分配”和“仅释放已分配内存的一部分”。一个缺点可能是释放内存需要O(logn)时间 谢谢 注:我已经看到了这个问题,但作者似乎还没有弄明白。没有说明malloc需要基于链
n
的内存段(这是正确的术语吗?)上,链表需要O(n)
时间来分配大小合适的内存块
然而,如果malloc
是基于树的,例如,一个间隔树,则只需要O(logn)
时间。此外,树可以在没有额外时间的情况下(就时间复杂度而言)满足这样的要求,例如“找到最小的可用内存块,其大小大于它们”
x“
”、“始终在可用内存的边界上分配”
和“仅释放已分配内存的一部分”
。一个缺点可能是释放内存需要O(logn)
时间
谢谢
注:我已经看到了这个问题,但作者似乎还没有弄明白。没有说明malloc需要基于链接列表。在平台之间,实现可能会发生变化。在一个平台上,速度可能是至关重要的,并且可以实现树,在另一个平台上,内存更昂贵,并且使用链表(或类似的)来尽可能地节省内存。没有说明malloc需要基于链表。在平台之间,实现可能会发生变化。在一个平台上,速度可能是至关重要的,树可以实现,而在另一个平台上,内存更昂贵,使用链表(或类似的)来尽可能节省内存。我不知道答案,但这里有一些想法: 绝对不要求以特定方式实现
malloc
。然而,在最坏的情况下,不平衡的树和链表一样糟糕。一个平衡的链表需要更多的维护。每个节点有两个链接的树也比单个链接列表占用更多内存。删除链表中的节点比较容易,在末尾插入节点也很容易
而且在大多数系统中,每个malloc
(几乎)都有一个免费
——因此,如果你通过让另一个变慢来让一个变快,那么你得到的收益很小
“下一次分配与上一次分配相同”也是比较常见的,这意味着如果最后一次分配是列表中的第一次,则是一个O(1)操作
在实时系统中,存储桶通常用于分配,因此有许多固定大小的存储桶,每次从主堆中分配某个内容时,该大小都会四舍五入到最接近的较大大小,释放后会进入该大小的存储桶(这是一个链表)。如果已经存在该大小的空闲元素,则使用该分配。除了分配/释放的速度为O(1)之外,这还有减少碎片的好处-将所有堆撕成小块,然后不留下任何大块不是完全不可能的,但至少不可能通过每次多分配一个字节来占用大部分内存,直到在一次分配中获得堆大小的一半
(同样,在Linux的GLIBC中,超过一定大小的分配根本不会出现在链表中——它们直接通过mmap
分配,并在调用free
时使用munmap
释放)
最后,算法的复杂性并不是一切——在现实生活中,它是花在重要事情上的实际时间——即使算法有O(n),但每一个操作都很快,它也可以超过O(logn)。类似地,特别是在C++中,小的分配是高度支配的,这意味着每个节点的更多内存开销是一个重要的因素。 < P>我不知道答案,但这里有一些想法: 绝对不要求以特定方式实现
malloc
。然而,在最坏的情况下,不平衡的树和链表一样糟糕。一个平衡的链表需要更多的维护。每个节点有两个链接的树也比单个链接列表占用更多内存。删除链表中的节点比较容易,在末尾插入节点也很容易
而且在大多数系统中,每个malloc
(几乎)都有一个免费
——因此,如果你通过让另一个变慢来让一个变快,那么你得到的收益很小
“下一次分配与上一次分配相同”也是比较常见的,这意味着如果最后一次分配是列表中的第一次,则是一个O(1)操作
在实时系统中,存储桶通常用于分配,因此有许多固定大小的存储桶,每次从主堆中分配某个内容时,该大小都会四舍五入到最接近的较大大小,释放后会进入该大小的存储桶(这是一个链表)。如果已经存在该大小的空闲元素,则使用该分配。除了分配/释放的速度为O(1)之外,这还有减少碎片的好处-将所有堆撕成小块,然后不留下任何大块不是完全不可能的,但至少不可能通过每次多分配一个字节来占用大部分内存,直到在一次分配中获得堆大小的一半
(同样,在Linux的GLIBC中,超过一定大小的分配根本不会出现在链表中——它们直接通过mmap
分配,并在调用free
时使用munmap
释放)
最后,算法的复杂性并不是一切——在现实生活中,它是花在重要事情上的实际时间——即使算法有O(n),但每一个操作都很快,它也可以超过O(logn)。类似地,特别是在C++中,小的分配是高度支配的,这意味着每个节点的更多内存开销是一个重要的因素。什么使你认为<代码> MALLC/<代码>使用链表?仅仅因为一个(许多)实现使用了它?@JoachimPileborg我读到了
pt