Как shared_ptr может нарушить выравнивание

Я читаю документы по DirectXMath и наткнулся на следующий отрывок:

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

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

1 ответ

Решение

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

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

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

Также не забудьте объявить деструктор частным, чтобы запретить (де) размещение в стеке.

Другие вопросы по тегам