嵌入式C++全局替换new运算符:是否需实现全部重载版本?
Great question—this is such a common gotcha when balancing STL convenience with RTOS heap safety in embedded C++! Let’s break down what you’ve covered so far and what might be missing:
What You’ve Already Covered
Your current overloads handle the most common single-object allocation/deallocation cases:
void * operator new(size_t n) noexcept(false);: This is called whenever you use a standard single-objectnew(e.g.,new MyObject()).void operator delete(void * p) noexcept(true);: Matches standard single-objectdeletecalls.void operator delete(void * p, size_t n) noexcept(true);: The C++11+ optimized overload that lets the compiler pass the original allocation size, which can help with more efficient deallocation. Compilers will prefer this when possible.
Key Overloads You’re Missing
If you want all heap allocations (including those from STL containers like vector) to use your FreeRTOS-thread-safe malloc, you need to add these critical overloads:
1. Array-Specific New/Delete
STL containers like vector use array allocation under the hood (they dynamically resize arrays of elements). The standard new[] and delete[] operators have their own global overloads that you haven’t defined yet. Without these, array allocations will fall back to the default malloc/free instead of your thread-safe implementation.
Add these:
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);
Implement them using your FreeRTOS thread-safe malloc/free just like your single-object versions.
2. Nothrow New (Optional but Recommended)
If your code (or the STL) uses the nothrow variant of new (e.g., new(std::nothrow) MyObject()), the standard library will use a different overload that doesn’t throw exceptions on failure. If you don’t define this, it’ll use the default malloc, which isn’t thread-safe for your RTOS.
Add these if you want full coverage:
#include <new> // For std::nothrow_t void* operator new(size_t n, const std::nothrow_t&) noexcept; void* operator new[](size_t n, const std::nothrow_t&) noexcept; // Corresponding delete overloads (optional but good practice) void operator delete(void* p, const std::nothrow_t&) noexcept; void operator delete[](void* p, const std::nothrow_t&) noexcept;
What You Don’t Need to Worry About (Probably)
- Placement New: The standard placement new (
new (ptr) MyObject()) doesn’t allocate memory—it just calls the constructor on pre-allocated memory. Since it doesn’t touch the heap, you don’t need to overload it unless you have custom placement logic (uncommon in most embedded RTOS setups).
STL Container Compatibility
Good news: As long as you’ve defined the global operator new/operator delete (and their array/nothrow variants), the default std::allocator used by STL containers like vector will automatically use your thread-safe implementations. No extra work needed there!
内容的提问来源于stack exchange,提问作者JuliusCaesar

