Как к уменьшению к соответствию станд.:: вектор эффективным памятью способом?

Я хотел бы к 'уменьшению к соответствию' std::vector, уменьшать ее способность до ее точного размера, так, чтобы дополнительная память была освобождена. Стандартный прием, кажется, тот, описанный здесь:

template< typename T, class Allocator >
void shrink_capacity(std::vector& v)
{
   std::vector(v.begin(),v.end()).swap(v);
}

Смысл уменьшения к соответствию должен сохранить память, но этот метод сначала не создает глубокую копию и затем подкачивает экземпляры? Так в какой-то момент - когда копия создается - использование памяти удвоено?

Если это так, существует ли более благоприятный для памяти метод уменьшения к соответствию? (В моем случае вектор является действительно большим, и я не могу позволить себе иметь обоих оригинал плюс копия его в памяти в любое время.)

8
задан Community 23 May 2017 в 11:45
поделиться

2 ответа

Что ж, если бы вы хотели изменить размер массива, что бы вы сделали? Вам нужно создать новый и скопировать все значения - будь то индивидуально или с помощью memcpy или что-то еще. Вы не можете изменить размер массива на C или C ++.

std :: vector в значительной степени гарантированно реализуется с использованием массива для его хранения (IIRC, стандарт не гарантирует, что это массив, но массив - единственное, что может удовлетворить различные требования API, например, насколько эффективной должна быть каждая операция; поэтому, по сути, это гарантировано, даже если эта гарантия не является явной). Поскольку это реализовано с использованием массива, и вы не можете изменять размер массивов без копирования, вы не можете изменять размер векторов без копирования.

Теоретически у вас может быть функция shrink_capacity () , которая скрывает тот факт, что вам пришлось временно более или менее удвоить ее требования к размеру, но поскольку std :: vector в настоящее время не имеет такой функции, вам нужно сделать явную копию. Уловка подкачки - хороший способ сделать это.

Если вы действительно заботитесь о памяти в таком случае, вы можете использовать указатели (или интеллектуальные указатели) вместо того, чтобы вектор содержал объекты напрямую. Это может быть не совсем желательно, но уменьшит ваши требования к памяти.

3
ответ дан 6 December 2019 в 01:39
поделиться

Если ваш новый размер составляет половину исходного, вы можете обойтись путем размещения нового вектора (или прямого массива dynaimc, если вектор может не делайте этого) в неиспользованный конец старого. Не уверен, что вектор хранит информацию в этой области памяти, так что это было бы очень взломано и страшно. Но это идея.

Теперь, когда я думаю об этом, операция типа memMove (), при которой вы копируете информацию в обратном порядке из последнего индекса, использованного в оригинале, в конец неиспользуемой области в оригинале, сохранит данные. Если вы сделали это новым размещением массива, вы могли бы указать его на то место, где новые данные могли бы существовать в середине исходной области памяти. Само по себе движение на месте.

-1
ответ дан 6 December 2019 в 01:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: