具有显式大小的可用内存

问题描述 投票:6回答:2

我正在主流操作系统中寻找类似于malloc / free的API,这些API允许我在分配和取消分配期间指定显式大小。我希望从中获得的好处是,当程序中已分配大小时,运行时可以在记账上花费更少的内存。

例如Windows我只找到了free()_aligned_free()_freea(),它们都不使用size作为第二个参数。

c++ c memory-management
2个回答
2
投票

我正在主流操作系统中寻找类似malloc / free的API,这些API允许我在分配和取消分配期间指定显式大小。

我一无所知。

我希望从中获得的好处是,当程序中已分配大小时,运行时可以在记账上花费更少的内存。

这个想法当然可以奏效,但是有两个缺点:

  1. 您必须在调用者跟踪其分配大小的对象与分配器仍需要记录其自身的对象之间划分分配区域。

    这将增加复杂性并可能导致内存碎片。

  2. [您必须分配精确程序要求的大小。

    也就是说,普通分配器可以决定为64字节请求返回96字节的块,因为它刚刚被释放,在缓存中很热,并且小于64字节的块被拆分和重新组合被认为是不值得的。

    通常,您的分配器无法执行此操作(仅限于舍入到下一个对齐的块大小)。]


  3. 当然,有很多专门的分配器可以明确地管理这些折衷。

当通用分配器不适合您的分配模式时,使用或编写这些代码是非常正常的事情。但是,它们通常不是由语言或操作系统提供的,因为它们是[[not

通用的。它们由库(或由您自己)提供。示例:

  1. 您以已知的固定大小分配和释放了很多对象。

    为它们写一个对象池分配器。它不需要跟踪分配大小,因为它总是相同的(通常是模板参数)。您也不需要在代码中显式跟踪它,因为它由类型隐含。

  2. 琐碎对象的可变大小分配都具有相同的生存期(例如,许多char缓冲区)。
  3. 写一个竞技场分配器。它不需要跟踪

    individual

    分配大小,因为您重置了整个分配器,而不是释放并重新分配单个对象。您永远不会显式删除分配对象,因为无论如何它们都是微不足道的。
NB。如果您选择使用new / delete重载来集成分配器(并认为它将受益于显式的size参数),则绝对可以使用Maxim指出的分配器,并请注意以下几点:

... [如果提供了用户定义的替换,则将调用[显式大小重载]],而不是[默认重载],但未指定[替换],即在删除不完整类型的对象和非类数组时将调用[指定]和普通可破坏的类类型。

0
投票
operator delete系列确实接受该大小。参见operator delete, operator delete[]
© www.soinside.com 2019 - 2024. All rights reserved.