У меня проблема (в частности, реализация MSFT VS 10.0 для ) std :: unique_ptrs. Когда я создаю из них std :: list, я использую вдвое больше памяти, чем когда я создаю std :: list только для базового объекта (примечание: это большой объект - ~ 200 байт, так что это не просто валяется дополнительный счетчик ссылок).
Другими словами, если я запустил:
std::list X;
X.resize( 1000, MyObj());
моему приложению потребуется вдвое меньше памяти, чем при запуске:
std::list> X;
for ( int i=0; i<1000; i++ ) X.push_back(std::unique_ptr(new MyObj()));
Я проверил реализацию MSFT и не вижу ничего очевидного - ни одного столкнулись с этим и есть какие-нибудь идеи?
РЕДАКТИРОВАТЬ: Хорошо, чтобы быть немного более ясным / конкретным.Это явно проблема использования памяти Windows, и мне явно чего-то не хватает. Теперь я попробовал следующее:
std :: list
из 100000 MyObj std :: list
из 100000 MyObj * std :: list
из 100000 int * std :: list
из 50000 int * В каждом случае каждый элемент add'l списка, будь то указатель или иным образом, увеличивает мое приложение на 4400 (!) байт . Это выпуск, 64-битная сборка, без какой-либо отладочной информации (Linker> Debugging> Generate Debug Info, установленной в No).
Мне, очевидно, нужно немного исследовать это, чтобы сузить его до меньшего тестового примера.
Для тех, кому интересно, я определяю размер приложения с помощью Process Explorer .
Оказывается, это была целиком фрагментация кучи. Как смешно. 4400 байт на 8-байтовый объект! Я переключился на предварительное выделение, и проблема полностью исчезла - я привык к некоторой неэффективности, полагаясь на распределение по объектам, но это было просто смешно.
Реализация MyObj ниже:
class MyObj
{
public:
MyObj() { memset(this,0,sizeof(MyObj)); }
double m_1;
double m_2;
double m_3;
double m_4;
double m_5;
double m_6;
double m_7;
double m_8;
double m_9;
double m_10;
double m_11;
double m_12;
double m_13;
double m_14;
double m_15;
double m_16;
double m_17;
double m_18;
double m_19;
double m_20;
double m_21;
double m_22;
double m_23;
CUnit* m_UnitPtr;
CUnitPos* m_UnitPosPtr;
};