Nekrolm / ubbook

Путеводитель C++ программиста по неопределенному поведению
1.08k stars 52 forks source link

Placement new and alignment #97

Closed sgshulman closed 1 year ago

sgshulman commented 1 year ago

Placment new с невыровненной памятью даёт UB. Как я понимаю, формально мы сталкиваемся с двумя пунктами стандарта:

8.5.2.4 пункт 17

When the allocation function returns a value other than null, it must be a pointer to a block of storage in which space for the object has been reserved. The block of storage is assumed to be appropriately aligned and of the requested size.

и 21.6.2.3 Non-allocating forms

operator new and operator delete. [[nodiscard]] void operator new(std::size_t size, void ptr) noexcept; Returns: ptr. Remarks: Intentionally performs no other action.

Т.е. при placement new ответственность за выравнивание лежит на вызывающем коде и никто не проверяет, что память выровнена. Остаётся понять, когда же это приводит к чему-то плохому. Возьмём какой-нибудь тип, для которого выравнивание важно, например, __m128i. Готово! Можно падать. Минимальный рабочий пример: https://godbolt.org/z/PxeqjqGhd

Замена buffer+1 на buffer в примере убирает segfault.

Nekrolm commented 1 year ago

Спасибо, отличный пример. Надо будет собрать под большой темой про доступ к невыравненной памяти

sgshulman commented 1 year ago

Полагаю, что https://github.com/Nekrolm/ubbook/blob/master/syntax/aligned_storage.md перекрывает пример выше