Как оператор new определяет размер выделяемой памяти
Что проверяют
Различаете ли вы new-выражение и функцию operator new. Размер определяет не «оператор» в рантайме, а компилятор. Следом спрашивают, откуда delete знает, сколько освобождать, и что меняется для массивов.
Как отвечать
new T(args) делает два шага. Сначала вызывает функцию выделения operator new(std::size_t) и передаёт ей sizeof(T): тип известен статически, это константа времени компиляции. Потом конструирует объект в полученной памяти. Если конструктор бросил исключение, память освободит парный operator delete.
Что отличает хороший ответ:
- массивы:
new T[n]вызываетoperator new[]с размером не меньшеn * sizeof(T). Для типов с нетривиальным деструктором компилятор обычно кладёт перед массивом служебное поле с количеством элементов, чтобыdelete[]знал, сколько деструкторов вызвать. Это деталь ABI, стандарт её не фиксирует; - переполнение: если
n * sizeof(T)не помещается вsize_t, с C++11 выражение бросаетstd::bad_array_new_length, а не выделяет урезанный блок; - выравнивание: для типов, у которых
alignofбольше__STDCPP_DEFAULT_NEW_ALIGNMENT__, с C++17 вызывается перегрузка сstd::align_val_t; - свой
operator newв классе: получает размер параметром, и для наследника он большеsizeof(Base), это важно для пулов памяти; - освобождение: размер блока помнит аллокатор в своих метаданных. С C++14 есть sized deallocation,
operator delete(void*, std::size_t), где размер снова подставляет компилятор.
Заодно про инициализацию: new int оставляет значение неопределённым, new int() обнуляет. При нехватке памяти бросается std::bad_alloc, а new (std::nothrow) вернёт nullptr.
Где спотыкаются
Называют malloc системным вызовом. Это библиотечная функция, к ядру через mmap или brk аллокатор обращается редко и крупными кусками, а operator new по стандарту вообще не обязан вызывать malloc.
Путают delete и delete[]. Несовпадение пары это неопределённое поведение, а не безобидная утечка пары байтов.
Удаляют наследника через указатель на базу без виртуального деструктора и ждут, что освободится верный объём. Это тоже неопределённое поведение.