Обновить

Комментарии 12

Однажды на одном из собеседований, меня спросили, ключевые отличия между new и malloc, вопрос интересный, так что я также хотел бы затронуть его в этой статье.

Ключевое отличие new от malloc в том, что new начинает object lifetime, а malloc нет. И reinterpret_cast тоже не начинает. Рекомендую копнуть в такие чудесные вещи как std::launder и std::start_lifetime_as.

Также new, помимо прочего, гарантирует корректное выравнивание для аллоцируемой памяти под объект, в обычный malloc - нет (но у него есть aligned версия).

Отчего, кстати, примерно все касты в ваших примерах и последующая запись в кастуемую память - UB.

Добрый день! Я очень благодарен вам, за уделенное вами время, вы заметили мои очень весомые ошибки. Про object lifetime, выравнивание и касты, полностью с вами согласен! Я постараюсь внести правки в статью в скором времени. Отличное замечание, я считаю std::start_lifetime_as и std::launcher отличной темой для следующих статей! 😅, Ваша критика очень конструктивна, спасибо вам что обратили внимание.

Ключевое отличие new от malloc в том, что new начинает object lifetime, а malloc нет

Маллок тоже начинает, но только для implicit-lifetime типов (как и memcpy, кстати).

Писать статью про С++ и при этом писать New, Delete... такое даже нейроссеть себе не позволяет.

Благодарю за отзыв, а ближайшие время отредактирую. Надеюсь ценность статьи была, чем регистр с большой буквы 😅

Очень понравилось слово "нейроссеть", я живо представил, как она нейроссыт. Извините.

Важно: Этот оператор невозможно перегрузить, или изменить его поведение, так как он следует собственной конкретной логике, он является основополагающим и вшит в сам язык C++

После этого читать статью дальше не буду. Как раз таки можно перегрузить как оператор new, так и оператор delete! Как в классе, так и глобально! Строго говоря, new даже не всегда выделяет память, он умеет вызывать конструктор на уже выделенной памяти (placement new). Невозможно перегрузить оператор new так, чтобы он не вызывал конструктор вообще, но так то можно перегрузить так, чтобы new не обращался к куче, что довольно дорого, а например обращался к пулу, который мы сами создаём в самом начале работы программы. Почитайте на cppreference про "operator new, operator new[]", там буквально есть раздел например "Class-specific overloads"

Просмотрел в итоге статью глазами, и вообще ничего не понял. Почему далее вы объясняете перегрузку, хотя до этого сказали, что нельзя перегружать...

Добрый день, я благодарю вас за ваше внимание к моей статье, вынужден попросить прощение, если некоторые разделы были непонятны. В статье выделил два основных термина operator new(new expression), который не может быть перезагружен стандартным способом, именно этот оператор и вызывает конструктор объекта, также помимо конструктора оператор вызывает функцию new (operator new) (только сейчас заметил противоречие в названиях 😅), задача которой заключается в выделении сырой памяти, чтобы operator new, мог разместить на ней объект. В зависимости от целей нашей программы, нам нечего не мешает перегрузить эту самую функцию new, для кастомных аллокаций, как вы упомянули, в пределах класса, так и глобально. Возможно я плохо понял суть вашего комментария, так что в случае чего, попрошу вас уточнить.

Как будто бы пост нейросеть писала. Жесть. Я тоже ровно до этого момента дочитал, и удивился

void* ptr = new void[10]; //10 конструкторов

:) :) :)

Современный с++ предлагает дофига возможностей управлять временем жизни переменных без new и delete. Да и в принципе комитет стандартизации рекомендует обходиться без них.

Знание new/delete, malloc/realloc/free и sbrk/virtualalloc критично только для написания системных библиотек и специализированных аллокаторов. Для остальных достаточно знать, что такие способности существуют.

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r-resource-management

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации