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

«В чем разница между free и delete в C++?» — вопрос из категории Управление памятью, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

free() и delete — это механизмы освобождения памяти, которые нельзя смешивать.

free() — функция стандартной библиотеки C (<cstdlib>). Она освобождает «сырую» память, выделенную функциями malloc(), calloc() или realloc(). free() не знает о типах C++ и не вызывает деструкторы объектов.

delete — оператор C++. Он выполняет две операции:

  1. Вызывает деструктор объекта (для освобождения ресурсов: закрытия файлов, освобождения другой памяти и т.д.).
  2. Освобождает память, выделенную для этого объекта оператором new.

Пример, демонстрирующий разницу:

#include <cstdlib>

class ResourceHolder {
    int* data;
public:
    ResourceHolder() { data = new int[100]; std::cout << "Resource allocatedn"; }
    ~ResourceHolder() { delete[] data; std::cout << "Resource freedn"; }
};

int main() {
    // C-стиль: НЕВЕРНО для объектов C++
    ResourceHolder* rh1 = (ResourceHolder*)malloc(sizeof(ResourceHolder));
    // Конструктор НЕ вызван! data не инициализирован.
    free(rh1); // Деструктор НЕ вызван! Утечка памяти для `data`.

    // C++-стиль: ПРАВИЛЬНО
    ResourceHolder* rh2 = new ResourceHolder(); // Вызывается конструктор
    delete rh2; // Вызывается деструктор (~ResourceHolder()), затем освобождается память

    return 0;
}

Важные правила:

  • Используйте delete для памяти, выделенной new.
  • Используйте delete[] для массивов, выделенных new[].
  • Используйте free() только для памяти, выделенной функциями семейства malloc.
  • Смешивание (new/free или malloc/delete) приводит к неопределенному поведению (undefined behavior).
  • В современном C++ предпочтительно использовать умные указатели (std::unique_ptr, std::shared_ptr) и контейнеры (std::vector), которые автоматически управляют памятью.