Я поддерживаю старое приложение C ++, в котором много классов, как показано ниже:
class ClassWithALotOfVectors
{
std::vector<int> _vector1;
std::vector<int> _vector2;
// a lot of other vector datamembers go here
std::vector<double> _vectorN;
};
то есть - тип данных, в котором содержатся векторы double или int.
Дело в том, что эти векторы никогда не заполняются одновременно, и, следовательно,
когда мы создаем 100000 экземпляров ClassWithALotOfVectors - использование памяти складывается
до внушительного числа, хотя только 10% этих векторов используются.
Поэтому я решил написать небольшой класс векторов «выделить по требованию».
Это обёртка вокруг std :: vector - где внутренний вектор создается только когда
доступ в первый раз (с использованием двух методов get - ref () и const_ref ())
Когда я заменил std :: vector в классе ClassWithALotOfVectors на compact_vector
как показано ниже:
class ClassWithALotOfVectors2
{
compact_vector<int> _vector1;
compact_vector<int> _vector2;
compact_vector<double> _vectorN;
};
провел несколько тестов, и результаты были многообещающими - использование памяти сократилось
резко, но вдруг обнаружил, что приложение не освобождает память
в конце - потребление памяти растет гораздо медленнее, чем
раньше было - но приложение, похоже, не освобождает память
в конце.
Можете ли вы взглянуть на мою реализацию compact_vector
и посмотрите, можете ли вы обнаружить что-то не так с управлением памятью.
template <class T> class compact_vector
{
public:
compact_vector<T>()
:_data(NULL)
{
}
~compact_vector<T>()
{
clear();
}
compact_vector<T>(const compact_vector<T> & rhs)
:_data(NULL)
{
if (NULL != rhs._data)
{
_data = new std::vector<T>(*(rhs._data));
}
else
{
clear();
}
}
// assignment
//
compact_vector<T> & operator=(const compact_vector<T> & rhs)
{
if (this != &rhs)
{
clear();
if (NULL != rhs._data)
{
_data = new std::vector<T>(*rhs._data);
}
}
return *this;
}
compact_vector<T> & operator=(const std::vector<T> & rhs)
{
clear();
if (!rhs.empty())
{
_data = new std::vector<T>(rhs);
}
return *this;
}
const std::vector<T> & const_ref()
{
createInternal();
return *_data;
}
std::vector<T> & ref()
{
createInternal();
return *_data;
}
void clear()
{
if (NULL != _data)
{
_data->clear();
delete _data;
_data = NULL;
}
}
private:
void createInternal()
{
if (NULL == _data)
{
_data = new std::vector<T>();
}
}
private:
compact_vector<T>(const std::vector<T> & rhs)
{
}
compact_vector<T>(std::vector<T> & rhs)
{
}
compact_vector<T>(std::vector<T> rhs)
{
}
std::vector<T> * _data;
};