首页 > 解决方案 > 在堆栈上分配小尺寸的矢量对象,或在堆上分配较大尺寸的矢量对象

问题描述

在实时应用程序中,例如音频编程,您应该避免在回调期间在堆中分配内存,因为执行时间是无限的。实际上,如果您的可执行文件内存不足,您将需要等待操作系统分配一个新块,这可能比下一次回调调用花费更长的时间。我可以将内存存储在堆栈上,例如使用可变长度数组 (VLA) 或alloca(),但如果数组太大,则会出现堆栈溢出。

相反,我正在考虑定义一个类,其接口类似于std::vector,但如果大小小于某个threshold,则在内部使用堆栈,否则使用堆(我更喜欢可能的无界操作而不是某个堆栈溢出)。对于堆部分,我可以使用std::vectoror new/ delete。但是堆栈呢?VLA 并alloca()在超出范围时被释放。我可以使用什么替代方案?

我可以使用std::array<T, threshold>,但这会浪费内存。我希望我threshold的顺序是2048

标签: c++vectorheap-memorystack-memory

解决方案


如果有可能需要将数据存储在堆栈中,并且大小是否大于阈值仅在运行时确定,那么您的类型将必须包含一些足够大的堆栈容器以容纳一些大小阈值(无论是 std::array 还是其他),引起您的关注

我可以使用 std::array,但这会浪费内存。我希望我的门槛在 2048 年左右。

不可避免。我认为没有办法解决这个问题。例如在代码中

uint32_t N = code_that_determines_size_at_runtime();
ThresholdContainer container(N);

编译器无法知道 N 是高于还是低于阈值。因此,要使其正常工作,ThresholdContainer 的内存布局必须包含堆栈内存,用于存储大小为阈值的数据,当 N > 阈值时,这些数据将未被使用和浪费。(将堆栈和堆内存与介于两者之间的一些迭代器拼接在一起将是可怕的,您可能需要连续的内存)。

另一方面,如果在编译时知道大小与阈值的关系,则可以定义一个以大小 N 为模板的类,如果 N< 阈值,则该类基本上包含 std::array 或向量,并提供通用接口。


推荐阅读