Преобразование между C ++ std :: vector и C массив без копирования - PullRequest
52 голосов
/ 14 ноября 2009

Я хотел бы иметь возможность конвертировать между std :: vector и лежащим в его основе C массивом int * без явного копирования данных.

Предоставляет ли std :: vector доступ к базовому массиву C? Я ищу что-то вроде этого

vector<int> v (4,100)
int* pv = v.c_array();

EDIT:

Кроме того, возможно ли сделать обратное, т.е. как бы я инициализировал std::vector из массива C без копирования?

int pv[4] = { 4, 4, 4, 4};
vector<int> v (pv);

Ответы [ 5 ]

84 голосов
/ 14 ноября 2009

Вы можете получить указатель на первый элемент следующим образом:

int* pv = &v[0];

Этот указатель действителен только до тех пор, пока вектор не перераспределен. Перераспределение происходит автоматически, если вы вставляете больше элементов, чем умещается в оставшуюся емкость вектора (то есть, если v.size() + NumberOfNewElements > v.capacity(). Вы можете использовать v.reserve(NewCapacity), чтобы вектор имел емкость не менее NewCapacity.

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

20 голосов
/ 31 мая 2014

В c ++ 11 вы можете использовать vector :: data () , чтобы получить указатель массива C.

20 голосов
/ 14 ноября 2009
int* pv = &v[0]

Обратите внимание, что это относится только к std::vector<>, вы не можете сделать то же самое с другими стандартными контейнерами.

Скотт Мейерс широко освещает эту тему в своих книгах.

16 голосов
/ 14 ноября 2009

Если у вас очень контролируемые условия, вы можете просто сделать:

std::vector<int> v(4,100);
int* pv = &v[0];

Имейте в виду, что это будет работать только до тех пор, пока вектор не будет расти, и вектор будет управлять временем жизни базового массива (то есть не удалять pv). Это не редкость при вызове базовых API-интерфейсов C, но обычно это делается с помощью неназванного временного объекта, а не путем создания явной переменной int *.

0 голосов
/ 18 мая 2012

Один из способов защитить себя от изменений размера - зарезервировать максимальное пространство (или больше), которое вам потребуется:

std::vector<int> v(4,100); //Maybe need 
v.reserve(40);             //reallocate to block out space for 40 elements

Это гарантирует, что push_backs не вызовет перераспределение существующих данных.

...