Я хотел бы к 'уменьшению к соответствию' std::vector
, уменьшать ее способность до ее точного размера, так, чтобы дополнительная память была освобождена. Стандартный прием, кажется, тот, описанный здесь:
template< typename T, class Allocator >
void shrink_capacity(std::vector& v)
{
std::vector(v.begin(),v.end()).swap(v);
}
Смысл уменьшения к соответствию должен сохранить память, но этот метод сначала не создает глубокую копию и затем подкачивает экземпляры? Так в какой-то момент - когда копия создается - использование памяти удвоено?
Если это так, существует ли более благоприятный для памяти метод уменьшения к соответствию? (В моем случае вектор является действительно большим, и я не могу позволить себе иметь обоих оригинал плюс копия его в памяти в любое время.)
Что ж, если бы вы хотели изменить размер массива, что бы вы сделали? Вам нужно создать новый и скопировать все значения - будь то индивидуально или с помощью memcpy или что-то еще. Вы не можете изменить размер массива на C или C ++.
std :: vector
в значительной степени гарантированно реализуется с использованием массива для его хранения (IIRC, стандарт не гарантирует, что это массив, но массив - единственное, что может удовлетворить различные требования API, например, насколько эффективной должна быть каждая операция; поэтому, по сути, это гарантировано, даже если эта гарантия не является явной). Поскольку это реализовано с использованием массива, и вы не можете изменять размер массивов без копирования, вы не можете изменять размер векторов без копирования.
Теоретически у вас может быть функция shrink_capacity ()
, которая скрывает тот факт, что вам пришлось временно более или менее удвоить ее требования к размеру, но поскольку std :: vector
в настоящее время не имеет такой функции, вам нужно сделать явную копию. Уловка подкачки - хороший способ сделать это.
Если вы действительно заботитесь о памяти в таком случае, вы можете использовать указатели (или интеллектуальные указатели) вместо того, чтобы вектор содержал объекты напрямую. Это может быть не совсем желательно, но уменьшит ваши требования к памяти.
Если ваш новый размер составляет половину исходного, вы можете обойтись путем размещения нового вектора (или прямого массива dynaimc, если вектор может не делайте этого) в неиспользованный конец старого. Не уверен, что вектор хранит информацию в этой области памяти, так что это было бы очень взломано и страшно. Но это идея.
Теперь, когда я думаю об этом, операция типа memMove (), при которой вы копируете информацию в обратном порядке из последнего индекса, использованного в оригинале, в конец неиспользуемой области в оригинале, сохранит данные. Если вы сделали это новым размещением массива, вы могли бы указать его на то место, где новые данные могли бы существовать в середине исходной области памяти. Само по себе движение на месте.