【发布时间】:2018-04-06 16:09:40
【问题描述】:
我使用嵌入式系统。通常这意味着我有一个小型微控制器,具有 64 - 512 KB 的 RAM 和 128 - 1024 KB 的闪存,如 STM32。我更喜欢使用 C++ 来编写这样的系统。但是我还没有找到可以接受的方法来处理常见的数据结构,例如堆栈、队列、映射等。
当然,STL 拥有所有这些和许多其他方便的东西,但是大多数 STL 容器需要支持异常和动态内存分配,这在嵌入式编程中通常是不受欢迎的。
我知道我们可以通过使用自定义分配器来避免这个问题,我们可以从静态对象池或类似的东西中分配内存。但是,我看到的主要问题是,当分配的空间不足以将新元素插入容器时,我们无法可靠地处理这种情况。我遇到的 STL 和其他类似 stl 的库只提出了两种选择:
- 断言。这意味着当分配的空间不足时系统会失败。
-
回调。好一点,但对我来说仍然不方便。
q.push(newElem); /* fails or just calls predefined callback * when not enough space in queue. */
也许我错了。但在我看来,最好的方法是返回状态以通知调用者容器中的新元素没有足够的内存。我想自己决定如何处理该错误。例如,我想删除新元素,向调试日志发送消息并恢复正常的程序流程。从我的角度来看,它看起来更可靠。
换句话说,我想要这样的东西:
queue<uint32_t, 128> q;
// some code ...
queue::status sts = q.push(newElem);
if (sts != queue::OK)
LOG("Not enough space in queue\r\n");
// continue normal program execution ...
有人建议如何处理那件事?
【问题讨论】:
-
听起来你对数据容器没有问题。相反,在我看来,您在决定错误报告策略时遇到了问题。
-
异常是报告任意嵌套调用失败的唯一明智的方法,所以如果你不能使用异常,你几乎必须确保失败永远不会发生。只要付出足够的努力和提前计划,这是可行的。在每个可能失败的操作之前预先分配足够的内存。使用像 boost 中的侵入式链表。对于向量和双端队列,请在添加内容之前保留。到处使用移动(而不是复制)。
-
@FrançoisAndrieux,我认为在很多情况下,只需删除新数据(我的意思是当容器已满时不要将其推入容器中)就足够了,并且不需要抛出异常或在调用堆栈的上方返回错误状态。无论如何,感谢您参考提升侵入性列表。我会尝试在那里挖掘。
-
@Lundin,我们可以在 C 上做的所有事情,我们都可以在 C++ 上做同样的事情。此外,C++ 还为我们提供了模板、函数重载、命名空间、OOP 等好东西。今天,我们可以在没有任何显着开销的情况下获得所有这些。而且我看不出有任何理由使用 C 而不是 C++。
-
没有。 C++ 在标准库中没有没有动态内存和异常的数据容器,C 在标准库中根本没有数据容器。所以,从这个角度来看,他们是平等的。无论如何,我们需要选择第三方库或自己编写。所以我选择的 c++ 不会影响这个问题。
标签: c++ data-structures stl embedded cortex-m