← Назад к вопросам

В чем разница между free и delete?

1.2 Junior🔥 182 комментариев
#Умные указатели и управление памятью#Язык C++

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между 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
В чем разница между free и delete? | PrepBro