В конструкторе Array
сразу после выделения и заполнения динамически выделенного буфера на ptr
буфер освобождается с
delete ptr;
Все обращения к буферу на ptr
после этой точки вызвать неопределенное поведение . Примечание: Это должно было быть delete[] ptr;
, чтобы гарантировать, что массив был освобожден правильно.
Решение: не делайте этого!
Добавьте деструктор к свободному ptr
, когда Array
выходит из области видимости и завершается с буфером.
// destructor for array class
Array::~Array()
{
delete[] ptr;
}
Компилятор автоматически сгенерирует для вас деструктор, но этот деструктор generi c не квалифицирован, чтобы знать, безопасно ли или нет delete[]
то, что находится в элементе-указателе. Это может быть не массив, выделение может принадлежать другому объекту (см. Что такое владение ресурсами или указателями? ) или, возможно, динамически не распределяться с new
.
. Примечание: специальные функции-члены по умолчанию, которые обрабатывают копирование этого объекта, будут бездумно копировать указатель, а не выделение, и оставят вас с двумя объектами, указывающими на одно и то же выделение. Рано или поздно это станет фатальным, потому что одна копия go выйдет из области видимости раньше другой, и если больше ничего не попытается получить доступ к освобожденному выделению и прервать программу, вторая delete[]
сломает программу. Эта проблема и ее решение подробно описаны в Что такое правило трех?
Общее правило - не создавать такой класс, а вместо этого использовать std::vector
. std::vector
делает все это и многое другое.