【发布时间】:2019-07-08 12:25:08
【问题描述】:
我是一名嵌入式软件开发人员,因此我不能总是使用所有不错的 C++ 功能。最困难的事情之一是避免动态内存分配,因为它在某种程度上适用于所有 STL 容器。
std::vector 在处理可变数据集时非常有用。但问题是分配(例如std::reserve)不是在初始化时完成或固定的。这意味着在进行复制时可能会出现内存碎片。
最好让每个向量都有一个分配的内存空间,这是向量可以增长到的最大大小。这将创建确定性行为,并可以在编译时映射微控制器的内存使用情况。当向量达到最大大小时调用push_back 将创建一个std::bad_alloc。
我读到可以编写std::allocator 的替代版本来创建新的分配行为。是否可以使用 std::allocator 创建这种行为,或者替代解决方案是否更合适?
我真的很想继续使用 STL 库并对其进行修改,而不是重新创建我自己的向量,因为与它们的实现相比,我更容易出错。
旁注 #1:
我不能将std::array 用作 1:它不是由我的编译器提供的,而 2:它确实具有静态分配,但我仍然必须管理 std::array 内的数据和缓冲区之间的边界.这意味着用我的分配属性重写std::vector,这是我想要摆脱的。
【问题讨论】:
-
是什么阻止你在初始化时调用
std::vector::reserve,你自己? -
@SamVarshavchik 许多嵌入式系统甚至没有定义
operator new。如果您在这些系统中调用动态分配函数,它将失败。 OTOH,有些确实有,但编码标准要求在启动时完成所有分配,在这种情况下.reserve()将起作用。 -
@SamVarshavchik 这确实是我目前的解决方案但是以汽车为例:禁止动态分配,因为行为需要是确定性的。在集合空间内创建
vector可以解决这个问题。 -
可以创建一个定制的分配器,它可以与标准容器一起使用,从内存池中分配内存。如果该内存池是在程序启动时分配的,那么程序启动后就不会重新分配。显然,有必要使用容器如何使用的知识来设计内存池本身,并在使用模式发生变化时相应地重新设计分配器(以及它如何管理内存池)。这是可能的,但并非微不足道 - 特别是如果您的开发人员希望任意调整标准容器的大小。
-
我没有说数据隐藏意味着复杂性和更长的开发时间,我说 C++ 就是这个意思。原因是不可避免的代码膨胀、复杂性和元编程疯狂,几乎可以保证随之而来。它根本不是一种非常适合嵌入式系统开发的语言。如果你有纪律不使用像 std::vector 这样的废话,那么你可以很好地使用 C++,但是具有不使用各种陷阱 C++ 特性的纪律的 C++ 程序员非常罕见。跨度>
标签: c++ embedded allocation