Давай рассмотрим, для начала, строку под комментарием.
ArrayArray[0] = *new Array<int>{10};
Что тут происходит.
ArrayArray[0]
вернет ссылку на
Array<int>
.
*new Array<int>{10}
выделяет память в куче под
Array<int>
, вызывает инициализатор
Array<int>::Array(int length)
, после чего делает разыменование получившегося указателя на
Array<int>
.
После этого для подготовленной ссылки на
Array<int>
будет выполнен оператор копирования по умолчанию, функциональность которого просто скопирует поля из объекта справа в объект слева от присвоения.
После этого результат
new Array<int>{10}
становится утекшим, т.к. указатель на него сразу становится потерян и освободить занимаемую им память становится невозможно.
Именно поэтому с этой строчкой у тебя "всё отрабатывает нормально". И нет, всё у тебя не отрабатывает нормально потому что память утекла.
Давай рассмотрим следующую строку.
ArrayArray[0] = Array<int>{10};
Что тут происходит.
ArrayArray[0]
вернет ссылку на
Array<int>
.
Array<int>{10}
инициализирует безымянный локальный объект на стеке, используя инициализатор
Array<int>::Array(int length)
.
После этого выполняется уже оператор перемещения по умолчанию, суть которого снова сводится к копированию полей из объекта справа в объект слева. После этого оба объекта ссылаются на одну и ту же выделенную память через поле
T *m_data
.
Далее безымянный локальный объект уничтожается, освобождая недавно выделенную память. А
ArrayArray[0]
в этот момент начинает ссылаться на освобожденную память.
Double deletion происходит тогда, когда
ArrayArray
в конце работы программы пытается удалить уже освобожденную память в
ArrayArray[0]
.
В твоем коде на лицо нарушение
инварианта типа.
Что нужно сделать.
Тебе должно уже стать понятно что проблема в твоем коде связана с поведением операторов копирования и перемещения по умолчанию. Но проблема у тебя, на самом деле, значительно шире. Потому что завтра ты ведь точно захочешь еще и инициализацию копией провести или вернуть объект по значению из функции. В этом случае тебя тоже ждут проблемы.
Решением твоих проблем будет соблюдение
правила 3/5/0.
Тебе нужно полноценно описать поведение объектов при копировании, перемещении, а так же при инициализации копией и инициализацией через перемещение.