Using C++ new() placement in embedded system
For new(), there are three definition in C++11, which are listed below.
|
throwing (1) |
void* operator new (std::size_t size); |
|
nothrow (2) |
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept; |
|
placement (3) |
void* operator new (std::size_t size, void* ptr) noexcept; |
The item (1) will return a non-null pointer to this block and throw a bad_alloc exception if the allocation is failure. The item (2) is same as item (1) but return a nullptr without exception. See example below.
struct TestClass { int data[100]; TestClass() {std::cout << "constructed [" << this << "]\n";} }; void MemoryTest(void) { std::cout << "1: "; TestClass * p1 = new TestClass; //throw std::cout << "2: "; TestClass * p2 = new (std::nothrow) TestClass; //no throw std::cout << "3: "; TestClass * p3 = new (p2) TestClass; //replacement delete p1; delete p2; }
The output is below.
1: constructed [0x3a9e00]
2: constructed [0x3a2768]
3: constructed [0x3a2768]
We can see the placement new() did not allocate memory. It can be used in embedded system for register operation. Example is shown below. It does not allocate the memory, you can use pControlReg->IsReady(), etc.freely;
class ControlRegC { public: bool IsReady() const; bool InterruptsEnabled() const; void EnableInterrupts(); void DisableInterrupts(); private: volatile uint8_t regValue; }; void NewControlReg(void) { ControlRegC * const pControlReg1 = new (reinterpret_cast<void*>(0xFFFF0010)) ControlRegC; //0xFFFF0010 is the register address. ControlRegC * const pControlReg2 = reinterpret_cast<ControlRegC*>(0xFFFF0010); //here is another solution, using reinterpret_cast directly }
浙公网安备 33010602011771号