template <class T> void container<T>::fillarray(container c)
{
//...
}
This function actually involves two container<T>
objects: *this
and c
.
Since you "pass by value" (the function parameter is not a reference), c
in fillarray
is created as a copy of the original c
in main
. In fillarray
you modify c
, which deletes and changes c.data
, but this->data
still contains the dangling pointer to the original storage. Before long, you get undefined behavior; luckily enough bad things happened you could tell something was wrong.
Per the Rule of Three (Plus Two), if a class has a destructor, you probably should not allow the compiler to generate the default copy constructor and copy assignment, and you may want to consider implementing a move constructor and move assignment.
The easiest, and sometimes best, way of meeting that rule is to disable copying:
template <class T> class container
{
public:
container(container const&) = delete;
container& operator=(container const&) = delete;
//...
};
Then the compiler will make sure you don't accidentally make a copy and get yourself into this sort of trouble.