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

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

Ответ

malloc() и new — операторы выделения памяти, фундаментально различающиеся по своей семантике в C++.

malloc() (из C) — функция, выделяющая блок неинициализированной памяти заданного размера в байтах. Возвращает void*, который требует явного приведения типа. Она не вызывает конструкторы объектов C++.

new (оператор C++) — выполняет две операции:

  1. Выделяет достаточную память для объекта (или массива объектов).
  2. Вызывает конструктор для инициализации объекта в этой памяти.
Сравнительная таблица: Критерий malloc() / free() new / delete
Язык C / C++ (как legacy) C++
Возвращаемый тип void* (требует приведения) Типизированный указатель (например, MyClass*)
Инициализация Нет (память содержит «мусор») Да (вызывается конструктор)
Размер Задается в байтах (sizeof) Вычисляется компилятором автоматически
Обработка ошибок Возвращает nullptr Генерирует исключение std::bad_alloc
Перегрузка Нет Да, можно перегружать для классов
Совместимость Работает с типами C (POD) Работает с любыми типами C++

Примеры:

// 1. Выделение памяти для примитивного типа
int* p1 = (int*)malloc(sizeof(int)); // Память не инициализирована
*p1 = 10; // Необходима ручная инициализация
free(p1);

int* p2 = new int(10); // Память выделена И инициализирована значением 10
delete p2;

// 2. Выделение памяти для объекта класса
class Widget {
    std::string name;
public:
    Widget(const std::string& n) : name(n) {}
};

// malloc: ТОЛЬКО память. Конструктор не вызван. ОПАСНО!
Widget* w1 = (Widget*)malloc(sizeof(Widget));
// w1->name находится в неопределенном состоянии. Использование -> UB.
free(w1); // Деструктор не вызван.

// new: Память + инициализация.
Widget* w2 = new Widget("test"); // Вызывается конструктор Widget(...)
delete w2; // Вызывается деструктор ~Widget()

Вывод: В C++ для объектов с нетривиальной логикой всегда используйте new/delete или, что лучше, умные указатели. malloc()/free() уместны только для низкоуровневого управления сырой памятью или при взаимодействии с C-библиотеками.