Nothing special would happen. You would write at some place in the middle of the allocated memory (100 bytes apart from the start, 99 bytes before the end of the allocated memory).
Then you would free that allocated memory. The compiler will handle it exactly as we would expect. The memory allocated by that is completely unrelated to null terminated strings. You could stick everything you want into that memory. It's some "raw" chunk of storage, you could even create some arbitrary C++ object into that memory (placement new).
Your bug is somewhere else. For example, some common error is this one, where the constructor is called once, but the destructor is called twice, double-deleting something:
struct A { P *p; A() { p = new P; } ~A() { delete p; } };
A getA() { return A(); } int main() { A a = getA(); }
Now, what happens is that the default constructor is called once, and the created object is copied zero or more times. But the destructor is run for each copy that's created. Thus, you will call the destructor on the pointer more than once, leading to such strange bugs. The correct way to fix that is to use a smart pointer, like shared_ptr
. As an exercise, you can also do it without, by writing proper copy constructors that copy the object over and allocate memory in the copy constructor, so that the copy and the respective original object keep distinct pointers.