Дикий выстрел в темноте ... У вас есть базовый класс, у которого нет виртуального деструктора, и вы фактически создаете экземпляр производного класса и сохраняете результат нового в указателе на базу.Вы удаляете через базовый указатель, и неопределенное поведение в данном конкретном случае вызывает этот эффект.
Почему я так считаю?Указатель, переданный на free
, не возвращается malloc
, так как он является нечетным адресом, он не может быть правильно выровнен, а malloc
всегда обеспечивает выровненные блоки памяти.Это означает, что память, которую указатель new
возвратил, и сохраненный указатель имеют смещение, которое указывает, что это, вероятно, базовый класс.Если бы у класса был виртуальный деструктор, то delete
мог бы определить наиболее производный тип объекта, и при этом он исправил бы указатель для ссылки на адрес, который был выделен с помощью new
.Без виртуального деструктора delete
преобразуется в obj->~MyObject(); free( obj );
без исправления смещения.
Еще одна вещь, которая может вызвать проблемы такого же типа, - выделение с помощью new[]
и освобождение с * 1014.* (new[]
выделит дополнительное место для хранения количества элементов, обычно перед возвращаемым указателем).Опять же, проблема заключается в том, что указатель, который передается в free
реализацией delete
, не исправляется в соответствии с указателем, возвращаемым malloc
... Но в этом конкретном случае смещение, вероятно, не будетнечетное число.