Overall I'm going to side with Oliver's comment that
This is not really c++ [...] it would be "safer and easier" with C++'s abstractions.
At your scale, you haven't shown any data convincing me that performance will influence choosing "old-style C++" over new, idiomatic C++; and anyway that shouldn't be your first consideration: your first consideration should be for correctness, robustness and testability. All of those have suffered given the use of unchecked allocation and unmanaged pointers.
My advice - which falls short of recommending specific C++(17|20) constructs since I'm not strong in that area - is to make it right-first, not fast-first. Write this in a style that has safe memory management practices and has solid unit test coverage, then profile it. If the performance is good enough (and I would be surprised if it isn't, but I've been wrong before) then leave it. If the performance suffers and it's the fault of your use of idiomatic C++ and reverting to unsafe memory management solves the problem, then fine - revert the slow pieces.
Put another way, you're either going to pay the cost of using newer C++ abstractions to play with memory safely, or you're going to pay in engineering time poring over Valgrind dumps.