Конкретно отвечая на ваш вопрос, оператор delete вызывает деструктор, а free - нет; следовательно, причина, по которой вы не хотите смешивать malloc / free с new / delete.
Когда библиотека компилятора захватывает память из кучи, она берет немного больше, чем вы просите, включая пространство для хранения, некоторые метаданные и, при необходимости, заполнение.
Скажем, вы malloc 128 байтов или новый массив из восьми 16-байтовых объектов. Компилятор может фактически захватить 256 байтов, включить небольшой блок управления кучей в начале, записать, что он дал вам 128, но захватил 256, и вернуть вам смещение в этот блок 256 где-то после его заголовка. Вам гарантировано, что из этого указателя у вас есть 128 байтов, которые вы можете использовать, но если вы выйдете за пределы этого, у вас могут возникнуть проблемы.
Операторы освобождения и удаления изнутри возьмут указатель, который вам передали, вернут назад известное смещение, прочитают блок заголовка и узнают, что освободили 256 байтов обратно в кучу.