В чем разница free, delete и delete[] в C++
Что проверяют
Понимаете ли вы, что в C++ выделение и освобождение идут строго парами, и чем это отличается от C. Следом спрашивают, что будет, если перепутать пару, и почему в современном коде delete руками почти не пишут.
Как отвечать
Три механизма, три пары:
free: освобождает память отmalloc,calloc,realloc. Работает с сырыми байтами, о типах не знает, деструкторы не вызывает. В C++ нужна в основном на стыке с C-библиотеками;delete p: пара дляnew T. Сначала вызывает деструктор~T(), потом отдаёт память черезoperator delete. Еслиpуказывает на базовый класс, деструктор базы обязан быть виртуальным, иначе это неопределённое поведение;delete[] p: пара дляnew T[n]. Вызывает деструкторы всех элементов в обратном порядке и освобождает блок черезoperator delete[]. Число элементов реализация обычно хранит перед массивом, но это деталь, на которую нельзя опираться.
Общие моменты: delete nullptr и free(nullptr) безопасны и ничего не делают. new при нехватке памяти бросает std::bad_alloc, а malloc возвращает нулевой указатель. Любое смешение пар это неопределённое поведение, а не просто утечка: free для памяти от new, delete для массива, delete[] для одиночного объекта.
Закончите современным подходом: владение выражают через RAII. std::unique_ptr<T> и std::make_unique, для массивов std::unique_ptr<T[]>, который сам вызовет delete[], а чаще просто std::vector. std::shared_ptr<T[]> поддерживается с C++17. Для поиска ошибок назовите AddressSanitizer (-fsanitize=address сообщает об alloc-dealloc-mismatch) и Valgrind.
Где спотыкаются
Говорят, что для int без деструкторов delete вместо delete[] безопасен. На практике часто «работает», но по стандарту это UB, и другой компилятор или аллокатор его проявит.
Сводят последствия к утечке. На деле возможны порча кучи и падение в совершенно другом месте программы.
Не упоминают виртуальный деструктор и двойное освобождение. После delete указатель остаётся висячим, повторный delete или обращение по нему тоже UB.