Мне известно о многих статьях по предотвращению фрагментации кучи. Мой вопрос касается конкретно того, что происходит, когда мы используем вектор для хранения данных:
class foo{
public:
std::vector<bar>; // Or I can have std::vector<bar*>
};
У меня нет проблем с использованием new или delete (у меня нет утечек памяти, и мне очень ясно, когда панель не используется, и я могу вызвать delete при необходимости). Но что касается фрагментации кучи, что лучше? Это делает переполнение стека более вероятным?
РЕДАКТИРОВАТЬ: У меня нет никакой новой информации, чтобы добавить. Я просто хотел поблагодарить всех и сказать, что я обнаружил, что любой вопрос, помеченный C ++, похоже, привлекает так много знающих и полезных людей. Это действительно довольно мило. Спасибо.
std::vector
гарантирует, что его содержимое будет храниться в постоянной памяти. Если вы храните объекты в своем векторе, то каждый объект будет находиться рядом друг с другом в большом куске памяти, но если вы поместите указатели на вектор, которые указывают на объекты, созданные с помощью new
Тогда каждый объект будет в случайных местах в памяти.
Поэтому первая версия (хранение объектов, а не указателей) лучше как для избежания фрагментации кучи, так и для использования кеша.
TL; DR, если у вас нет веских причин, с измерениями звука, всегда предпочитайте использовать vector
с типами значений.
Я бы поспорил за std::vector<bar>
форма. Если у вас нет других (взвешенных) причин, почему гарантированная непрерывная память vector
с типом значения это лучшая идея. Когда вектор выделяет непрерывный блок памяти, объекты будут размещаться в памяти рядом друг с другом (с некоторым запасом). Это позволяет хост-системе и среде выполнения лучше избегать фрагментации. Выделение объектов по отдельности может привести к фрагментации, поскольку вы не контролируете, где они расположены.
Я отмечаю ваши опасения по поводу стека; vector
имеет небольшое выделение стека, так что это не должно быть проблемой, «обычный» распределитель std::allocator
использования new
выделить память для vector
в кучу.
Зачем vector
всегда быть любимым? Херб Саттер подробно рассказывает об этом; http://channel9.msdn.com/Events/Build/2014/2-661 с поддерживающими графиками, диаграммами, объяснениями и т. д. около отметки 23:30, и он берет материал Бьярне около отметки 46:00.
У ОП, похоже, есть принципиальное недопонимание того, что std::vector
делает: выделяет непрерывный блок памяти в кучу, вам не нужно беспокоиться о вашем стековом пространстве при использовании vector
! Поэтому, когда вам действительно не нужно ничего хранить, кроме самих объектов, просто положите их в свой vector
и ты хороший.
Так std::vector<bar>
кажется правильным выбором в вашем случае. Кроме того, не беспокойтесь о фрагментации кучи преждевременно, пусть об этом беспокоится компилятор. (Но вы должны беспокоиться о кормлении предварительного сборщика, вот почему std::vector<bar>
должен быть вашим стандартным выбором для хранения что-нибудь.)
Используйте вектор указателей в следующих случаях:
Если вам нужны указатели, я настоятельно рекомендую использовать умные указатели.
В других случаях вы должны предпочитать хранить объекты по значению, так как это обычно более эффективно.