В чем разница между free и delete?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между free и delete
Главное правило: free() и delete — это парные операции. free используется для malloc, delete для new.
Основные отличия
1. Вызов деструктора
Самое важное: delete вызывает деструктор, free — нет.
class Resource {
public:
Resource() { data = new int[100]; }
~Resource() { delete[] data; }
private:
int* data;
};
// new/delete (правильно)
Resource* r = new Resource(); // конструктор вызван
delete r; // деструктор вызван, память очищена
// malloc/free (УТЕЧКА)
Resource* r = (Resource*)malloc(sizeof(Resource));
// конструктор НЕ вызван
free(r); // НЕ вызывает деструктор, утечка памяти
2. Источник (C vs C++)
- free — функция из C (stdlib.h)
- delete — оператор языка C++
3. Для массивов
// new/delete для одного
MyClass* obj = new MyClass();
delete obj;
// new[]/delete[] для массивов
MyClass* arr = new MyClass[10];
delete[] arr; // ВАЖНО: delete[], не delete
// malloc/free — одно для всего
MyClass* p = (MyClass*)malloc(10 * sizeof(MyClass));
free(p);
Почему смешивать нельзя?
new + free = undefined behavior
Когда выделяешь new, компилятор добавляет метаданные. free ожидает другой формат от malloc. Результат — undefined behavior.
malloc + delete = undefined behavior
Тоже самое в обратном направлении.
Переопределение
В C++ можно переопределить operator new и delete для кастомных аллокаторов:
void* operator new(size_t size) {
return myAllocator.allocate(size);
}
void operator delete(void* ptr) noexcept {
myAllocator.deallocate(ptr);
}
Это невозможно с free — это функция C.
Метаданные
new и malloc добавляют метаданные перед данными. Они используют разные форматы, смешивание приводит к undefined behavior.
Когда использовать?
delete — всегда в современном C++:
// Современный стиль
std::unique_ptr<MyClass> obj = std::make_unique<MyClass>();
// При выходе из scope — автоматически delete
std::shared_ptr<MyClass> shared = std::make_shared<MyClass>();
// При обнулении последней ссылки — автоматически delete
free — только для malloc:
int* buffer = (int*)malloc(1000 * sizeof(int));
free(buffer);
Практический пример
// БАГИ: утечка деструкторов
void processData(int size) {
MyClass* data = new MyClass[size];
try {
// обработка
} catch (...) {
free(data); // НЕ вызывает деструкторы
throw;
}
delete[] data;
}
// Правильно
void processData(int size) {
auto data = std::make_unique<MyClass[]>(size);
// Автоматически delete[] при выходе
}
Заключение
- Правило парности: new/delete, malloc/free
- delete вызывает деструкторы, free — нет
- Смешивание = undefined behavior
- Используй std::unique_ptr и std::shared_ptr вместо raw new/delete