Search code examples
c++armheap-memorynew-operatormbed

Wrong dynamic memory size allocated for Mbed BufferedSerial object


I'm trying to allocate two instances of mbed::BufferedSerial object in heap on nrf52840. First allocation succeeds and first instance of serial port works fine, however, after creating the second serial port object instance, the first instance stops working. Debugging shows that the second object overwrites the 16 last bytes of the first object in memory. The reason is that while sizeof(BufferedSerial object) is 856 bytes, the new operator only allocates 840 bytes, and therefore, the last 16 bytes are overwritten on the next heap allocation.

The count parameter passed is 840B: operator new (std::size_t count)

The size of object after creation is 856B: sizeof(*g_serial_port[0])

Does anyone have any idea why this happens and how to fix it? The piece of code that does the allocation is simply like this (compiled with GNU Tools Arm Embedded 9 2019-q4-major):

serial_api.cpp

static mbed::BufferedSerial *g_serial_port[2] =
{ NULL };

extern “C” void create(id, tx , rx)
{
    g_serial_port[id] = new mbed::BufferedSerial(tx, rx);
}

main.c

int main()
{
    create(0, P1_14, P1_15); //the heap allocated is 16 bytes smaller than the object
    create(1, P1_12, P1_13); // this object's allocation overwrites the last 16 bytes of the previous one.
    …
}

Solution

  • David Schwartz's comment gave me a clue to look for mismatched pre-processor MACRO definitions. The problem was with DEVICE_SERIAL_FC pre-processor macro. When mbed was built as a library, the macro was enabled. However, when the library and its header files were used in the project, it was disabled. This mismatch caused the problem.