There are a couple of problems with your code:
Obviously the first one is the mixing of free/delete
In C++ code to avoid confusion it is best not to use malloc/free. But if you must then free() can only be used to free pointers created via malloc/calloc/realloc. Pass any other pointer and your program is likely to go boom.
Adding more context to this problem is that the C++ versions new/delete not only allocate/release memory but initialize/de-initialize the object via the constructor/destructor. The destructor is more obscure as it is used to release resources that were created in the constructor. In your case the constructor allocates memory and the destructor deallocates the memory. But since you are using free none of the destructors would get called (so you have a memory leak (in each cell)).
The other problem you have is that the compiler generated versions of the copy constructor and assignment operator (these are two of four methods that can be automatically generated by the compiler for each class) do not work well when you have RAW pointers in your class.
For example:
{
Foo a; // a.x = pointer to a dynamically allocated location
Foo b(a); // b.x = a.x (whoops)
} // Both a and b go out of scope here.
// This means b's destructor is called
// Followed by a's destructor (now here is where the problem is)
// Because b.x = a.x you have now called delete on the same pointer twice.
Double deletion of the same pointer is not allowed.
What you need to do is look up the Rule of Three
But basically when your class contains a RAW pointer you also want to make sure that Copy Constructor/Assignment operator/Destructor are all defined.
So things to remember when allocating memory:
- new must be matched by a delete.
- new [] must be matched by a delete [].
- free() can only be used on the result of malloc/calloc/realloc
Once you have mastered those rules:
- Try and never use delete.
- Learn about smart pointers and containers (let them do the work for you).
If your object contains a RAW pointer (which should be rare because you have learn about smart pointers and containers). You must know the rule of three and how to make sure the compiler generated methods do not make a mess of your object accidentally.