Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么malloc()基于链表?_C++_C_Memory_Memory Management_Data Structures - Fatal编程技术网

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