EDIT1: я знаю, что нет места для удаления. Но мне интересно, почему просто оператор удаления не может удалить память, не заботясь о том, как выделена та память, на которую указывает указатель?
Поскольку каждая разновидность выделения памяти использует некоторую специфичную для реализации отслеживание памяти (обычно блок заголовка, который предшествует адресу пользователя), и это позволяет выделению/освобождению работать только при правильном сочетании:
new должен быть в паре с delete
new[] должен сочетаться с delete[] (хотя большинство реализаций простят смешение new и new[])
malloc и Фрид должны сочетаться с free
CoTaskMemAlloc пар с CoTaskMemFree
alloca пары ни с чем (об этом позаботится раскрутка стека)
MyCustomAllocator пар с MyCustomFree
Попытка вызвать неправильный делокатор приведет к непредсказуемому поведению (скорее всего, ошибка seg сейчас или позже). Поэтому вызов delete в памяти, выделенной чем-то другим, кроме new, приведет к плохим последствиям.
Кроме того, новое место размещения может быть вызвано по любому адресу, который может даже не быть выделенным адресом. Его можно вызвать по адресу, расположенному в середине какого-то более крупного объекта, его можно вызвать по области с отображением памяти, его можно вызвать по необработанной виртуальной фиксированной области, что угодно. delete попытается во всех этих случаях сделать то, что говорит ему его реализация: вычесть размер заголовка, интерпретировать его как заголовок new, связать его обратно с кучей. Кабум.
Тот, кто знает, как освободить память нового адреса размещения, это вы, поскольку вы точно знаете, как была выделена эта память. delete будет делать только то, что знает, и это может быть неправильно.
person
Remus Rusanu
schedule
14.08.2011