我使用嵌入式系统。通常这意味着我有一个小型微控制器,具有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 ...
有人建议如何处理那件事?
答案 0 :(得分:0)
你可以使用一个自定义分配器,当它耗尽空间时抛出std :: bad_alloc,然后在你的代码中包含依赖于在异常处理块中成功插入的部分并处理catch子句中的分配失败
std::queue <message> Queue;
try
{
Queue.insert (message {"hello world"});
}
catch (std::bad_alloc const & Error)
{
LOG (Error.what ());
}
对于简单的场景,这有点冗长,小心(使用RAII)它可以是一个强大的工具。此外,如果您有这些简单的场景分配,您可以在模板中隐藏此模式。
template <typename fn>
void log_failure_and_contiue (fn Fn)
{
try
{
Fn ();
}
catch (std::bad_alloc const & Error)
{
LOG (Error.what ());
}
}
std::queue <message> Queue;
log_failure_and_continue ([&] {
Queue.insert ({ "Hello World!" });
});
从性能的角度来看,大多数编译器都实现了零成本异常处理,所以如果抛出异常,你只会受到攻击,我认为在这种情况下应该很少。