2015-07-05 6 views
6

Я читаю документы на DirectXMath, и наткнулся на следующий проход:Как shared_ptr нарушить Alignment

В качестве альтернативы обеспечении согласованности в вашем C++ класса непосредственно перегрузкой новые/удалить, вы можете использовать pImpl идиома. Если вы гарантируете , ваш класс Impl выровнен через __aligned_malloc внутренне, вы можете , затем свободно использовать выровненные типы во внутренней реализации. Этот является хорошим вариантом, когда «общедоступный» класс является стандартом Windows Runtime ref или предназначен для использования с std :: shared_ptr <>, который в противном случае нарушает тщательное выравнивание.

Я не понимаю, как shared_ptr может внести изменения в стратегию выравнивания, у него есть только указатель, он не выделяет объект.

+0

Согласен. Мне кажется, что документы устарели. в C++ 11 вы можете указать выравнивание вашего типа данных с помощью атрибутов. –

ответ

10

Вы правы, std::shared_ptr не влияет на выравнивание. Он просто принимает указатель на уже выделенный объект, поэтому, если это распределение привело к смещенному объекту, проблема не в std::shared_ptr, это с этим распределением.

Но std::shared_ptr часто используется с std::make_shared. std::make_shared<T> выполняет одно выделение резервной памяти как для структуры управления std::shared_ptr, так и для экземпляра T. Это распределение не выполняется с использованием любого класса operator new (и не должно быть). Если класс operator new устанавливает более строчное выравнивание, чем то, что делает распределитель по умолчанию, тогда легко увидеть, как это может произойти, когда используется распределитель по умолчанию.

+1

Кроме того, даже если '' operator new'' использует выравнивание по 16 байт (например, с родным x64), стандарт не требует дополнительного пространства, выделенного с помощью '' std :: make_shared'', для выравнивания класса сам. –

+0

Принял мне тысячу часов отладки, чтобы наконец найти виновника. Благодаря! – rwols