用于嵌入式系统的C++数据容器
C++ data containers for embedded systems
我使用嵌入式系统。通常,这意味着我有一个小型微控制器,有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 queuern");
// continue normal program execution ...
有人建议怎么处理那件事吗?
您可以使用一个自定义分配器,当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!" });
});
从性能的角度来看,大多数编译器都实现零成本的异常处理,因此只有在抛出异常时才会受到影响,我认为在这种情况下这种情况应该很少见。
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 在运行时处理类型擦除的数据-如何不重新发明轮子