Используйте :: std :: vector для создания массива - PullRequest
0 голосов
/ 17 апреля 2019

Я хочу вырастить :: std :: vector во время выполнения, вот так:

::std::vector<int> i;
i.push_back(100);
i.push_back(10);

В какой-то момент вектор закончен, и мне не нужны дополнительные функции :: std:: vector предоставляет больше, поэтому я хочу преобразовать его в C-Array:

int* v = i.data();

Поскольку я буду делать это более одного раза, я хочу освободить всю кучную память :: std :: vectorзарезервировано, но я хочу сохранить данные вот так (псевдокод):

free(/*everything from ::std::vector but the list*/);

Кто-нибудь может дать мне несколько советов по этому поводу?

Заранее спасибо, Джек

Ответы [ 4 ]

6 голосов
/ 17 апреля 2019

Во всех реализациях, которые я видел, выделенная часть вектора - это ... сам массив.Если вы знаете, что он больше не будет расти, вы можете попытаться уменьшить его, чтобы высвободить, возможно, неиспользуемую память:

i.shrink_to_fit();
int* v = i.data();

Конечно, ничто не гарантирует, что реализация что-нибудь сделает, но единственная надежная альтернатива будетчтобы выделить новый массив, переместить данные из вектора в массив и очистить вектор.

int *v = new int[i.size];
memcpy(v, i.data, i.size * sizeof(int));
i.clear();

Но я действительно сомневаюсь, что таким образом вы получите существенный выигрыш ...

5 голосов
/ 17 апреля 2019

Вы можете использовать содержимое std::vector как массив C без необходимости что-либо копировать или выпускать.Просто убедитесь, что std::vector не требует, чтобы ваш указатель был действительным (и что дальнейшие изменения, которые могут вызвать перераспределение, выполняются для самого вектора).

Когда вы получаете указатель на внутреннее хранилище через data() вы на самом деле ничего не выделяете, просто ссылаетесь на уже выделенную память.

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

1 голос
/ 17 апреля 2019

У вас есть два варианта:

  1. Сохранять данные в векторе, но вызывать shrink_to_fit .Все накладные расходы у вас будут - это дополнительный указатель (на конец вектора).Он доступен начиная с C ++ 11
  2. Копирование данных во внешний массив и уничтожение векторного объекта:

Вот пример:

std::vector<int> vec;
// fill vector
std::unique_ptr<int[]> arr(new int[vec.size()]);
std::copy(vec.begin(), vec.end(), arr.get());
0 голосов
/ 17 апреля 2019

ОК, спасибо всем, кто это сделал, я предложил следующее решение:

auto v = new ::std::vector<int>();
// fill the vector
v->shrink_to_fit();
int* g = v->data();
free(v); // will free the memory the vector occupies, but not that of the array, since it does not call the destructor

Если я когда-нибудь столкнусь с реализацией, в которой :: std :: vector выделяет больше, чем массивЯ просто #if и освободить соответствующие адреса.

Спасибо за вашу помощь, Джек

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...