繁体   English   中英

为什么std :: allocator :: deallocate需要一个大小?

[英]why does std::allocator::deallocate require a size?

std::allocator是基础内存模型的抽象,它包装了调用newdelete的功能。 delete不需要大小,但是deallocate() 需要它。

无效的deallocate(T * p,std :: size_t n);
“参数n必须等于最初产生p的对allocate()的调用的第一个参数;否则,行为是不确定的。”

为什么?

现在,我必须在取消分配之前进行其他计算,或者开始存储传递给分配的大小。 如果我不使用分配器,则不必这样做。

std::allocator API( Allocator概念 )的设计是为了简化潜​​在的替换工作。

std::allocator是基础内存模型的抽象

不一定是! 通常,分配器不需要使用C mallocfree ,也不需要delete或就位new 是的, 默认情况下通常会这样做,但是分配器机制不仅仅是对C内存模型的抽象。 与众不同通常是自定义分配器的全部目的。 请记住,分配器是可替换的:特定的std::allocator可能不需要释放大小,但任何替换都可能。

符合标准的std::allocator可以自由声明您确实传递了正确的n来进行deallocate ,否则可以依赖于正确的大小。

碰巧mallocfree将块大小存储在其数据结构中。 但是总的来说,分配器可能不会这样做,而要求这样做是过早的悲观化。 假设您有一个自定义池分配器,并且正在分配int的块。 在典型的64位系统上,存储64位size_t和32位int会产生200%的开销。 分配器的用户可以更好地定位存储大小,或者以更便宜的方式确定大小。

好的malloc实现不会为每个小分配存储分配大小。 它们并能够从指针本身得出块大小,例如,通过从块指针中得出块指针,然后检查块头中的块大小。 那当然是一个细节。 你可以得到下界使用特定平台的API,如大小malloc_size在OS X上, _msize在Windows上, malloc_usable_size在Linux上。

对于内存分配算法来说,使它们所需的开销最小化通常很有用。 某些跟踪空闲区域而不是已分配区域的算法可以将开销总量减少到一个低恒定值,每块开销为零(簿记信息完全存储在空闲区域内)。 在使用这种算法的系统上,分配请求从空闲池中删除存储,而解除分配请求将存储添加到空闲池中。

如果使用池的连续区域满足了对256和768字节的分配请求,则内存管理器状态将与使用同一区域满足两个对512字节的请求的情况相同。 如果向内存管理器传递了指向第一个块的指针并要求释放它,则它将无法知道第一个请求是用于256字节,512字节还是任何其他数字,因此也就无法知道应该将多少内存添加回池中。

在这样的系统上实现“ malloc”和“ free”将要求它在存储区的开头存储每个块的长度,并返回一个指针,指向在该长度之后可用的下一个适当对齐的地址。 实现当然可以做到这一点,但是它将为每个分配增加4-8字节的开销。 如果调用方可以告诉释放例程将多少存储添加回内存池,则可以消除此类开销。

此外,很容易适应这个设计要点:只需将事物分配为struct ,并将大小存储为该struct内的元素。 您的调用deallocator的代码现在知道要提供什么值,因为结构本身包含它。

这样,您实际上就是在完成任何其他语言实现可能正在您做事情。 您只是在明确地做同样的事情。

现在,考虑到我们正在谈论的是C ++ ,它已经内置了许多优秀的容器类,因此,如果可以避免的话,我谨鼓励您避免“自己动手”。 只要找到一种使用该语言和标准库已经提供的漂亮容器类的方法即可。

否则,请确保将您在此处构建的内容打包为本地容器​​类。 确保处理分配器和取消分配器的逻辑在程序中仅出现一次。 (即,在此类之内。)大量使用专门设计用于检测错误的逻辑。 (例如,一个哨兵值,它在分配对象时插入到对象中,并且必须在释放对象时找到,并且在对象被抹除之前就被删除。显式检查要存储的size-value确保有道理。等等。)

不需要跟踪大小。 标准分配器不跟踪大小,因为它假定所有分配的大小。 当然,出于不同的目的有不同类型的分配器。 您可能已经猜到,块大小分配器的大小是固定的。 诸如视频游戏之类的某些应用程序会预先预先分配内存,从而消除了需要跟踪每次分配大小的开销。

标准库尝试尽可能通用 一些分配器需要跟踪大小,而其他则不需要,但是所有分配器都必须符合接口。

我没有确凿的证据,但是我的直觉是不需要使用C ++运算符new / delete分配器,并且不妨使用不具有分配数组和了解其大小的能力的内存管理例程-例如malloc,例如。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM