malloc(), free(), and realloc() are C library functions, that know absolutely nothing about C++ classes, their constructors, and destructors.

You are using malloc() with placement new to construct a std::string using malloc-ed memory. This is fine.

But then, you're using realloc() to reallocate the allocated memory.

Copying/moving C++ objects in memory must be done using the respective objects' copy/move constructors. Copying/moving C++ objects in memory cannot be done with realloc().

The only way to do this is to malloc() a new memory block, use placement new to invoke the objects' copy/move constructors in order to copy/move them into the new memory block, and finally invoke the destructor of the objects in the old memory block, after which it can be free()-ed.