【发布时间】:2019-08-20 21:13:20
【问题描述】:
我在(嵌入式)C++ 应用程序中使用 RTOS。由于我正在处理嵌入式目标,因此我尝试将堆分配保持在最低限度。但是在某些时候,像向量这样的 STL 类会非常方便。
因为我使用的是 RTOS,所以我必须确保 new/malloc() 调用是线程安全的。幸运的是,我的 RTOS (FreeRTOS) 提供了它自己的(线程安全的)malloc() 例程。我只需要使用它们。
到目前为止,我实现了以下新/删除对并将其链接到二进制文件中。
void * operator new(size_t n) noexcept(false);
void operator delete(void * p) noexcept(true);
void operator delete(void * p, size_t n) noexcept(true);
但是看着这个
https://en.cppreference.com/w/cpp/memory/new/operator_new
向我展示了十几个新的重载(以及删除的重载)。 是否所有新重载或删除重载都默认替换为我的替换,或者我缺少运算符重载?
【问题讨论】:
-
每个分配东西的 STL 类都提供一个模板参数来指定使用的分配器:
template< class T, class Allocator = std::allocator<T> > class vector; -
您为什么认为标准分配函数不是线程安全的?
-
您需要替换程序使用的运算符
new(以及相应的运算符delete)的所有重载。您可能会很幸运,但是对于一个运算符new的重载默认调用另一个运算符并没有特别的保证。在担心线程安全的分配器/释放器之前,我会认真地看看系统是否可以设计为避免分配和动态释放(例如在启动期间分配,在启动线程之前分配,并在所有启动的线程完成后释放)——即使有线程安全,动态分配和释放也会产生不确定性 -
通常,在嵌入式系统中,
operator new被定义为只是对malloc的调用(例如,在 Arduino 中,new和new[]都是这样定义的,这反过来又使得使用new[]分配和使用delete错误地解除分配安全但不可移植)。您应该在实施您的通话之前检查发生了什么。 -
不幸的是还有另一个问题。如果我尝试使用默认的 new 运算符分配大量数据,则会引发硬错误。这实际上是我更换新操作员的主要意图。是的,在我的嵌入式系统上 new 只是对 malloc 的调用,它不是线程安全的。所以基本上你是说我不能确定特定的 STL 类实际使用的是哪个新运算符? Allocator 类型始终设置为 std::allocator
标签: c++ new-operator