В чем разница malloc и new в C++
Что проверяют
Понимаете ли вы, что в C++ выделение памяти и создание объекта это два разных шага, и что new делает оба, а malloc только первый. Следом обычно спрашивают, что будет, если освободить память не той функцией, и пишете ли вы голый new в современном коде.
Как отвечать
- природа:
mallocэто функция из<cstdlib>, она принимает число байт и возвращаетvoid*, который в C++ приходится явно приводить.newэто выражение языка: оно само считает размер по типу, получает память черезoperator new, вызывает конструктор и возвращает типизированный указатель; - инициализация: после
mallocв памяти нет объекта, только байты.new T(args)вызывает конструктор. Для встроенных типов есть тонкость:new intоставляет значение неопределённым, аnew int()иnew int{}дают ноль; - ошибка выделения:
mallocвозвращает нулевой указатель, обычныйnewбросаетstd::bad_alloc, аnew (std::nothrow) Tвозвращаетnullptr; - освобождение: пары строгие,
mallocсfree,newсdelete,new[]сdelete[].deleteсначала вызывает деструктор,freeпро деструкторы не знает; - гибкость:
operator newможно перегрузить для класса или заменить глобально, а placement new (new (buf) T) создаёт объект в уже выделенной памяти. Уmallocзато естьrealloc, уnewаналога нет.
Закончите практикой: в прикладном коде голый new почти не пишут, память держат std::unique_ptr через std::make_unique, std::shared_ptr и контейнеры. malloc остаётся для работы с C API, которое потом само вызовет free, и для своих аллокаторов.
Где спотыкаются
Смешивают пары: delete на памяти от malloc или delete вместо delete[]. Это неопределённое поведение, а не «просто не вызовется деструктор», и на другой платформе такой код может упасть.
Проверяют результат обычного new на nullptr. Он не вернёт ноль, такая проверка мёртвый код: ошибку ловят через std::bad_alloc или используют nothrow.
Применяют realloc к массиву объектов с нетривиальным копированием, например к массиву std::string. realloc переносит байты, не вызывая ни конструкторов, ни деструкторов, и объекты внутри ломаются.