Преобразование между С++ std::vector и массивом C без копирования
Я хотел бы иметь возможность конвертировать между 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);
Ответы
Ответ 1
Вы можете получить указатель на первый элемент следующим образом:
int* pv = &v[0];
Этот указатель действителен только до тех пор, пока вектор не перераспределяется. Перераспределение происходит автоматически, если вы вставляете больше элементов, чем будет соответствовать оставшейся емкости вектора (то есть, если v.size() + NumberOfNewElements > v.capacity()
. Вы можете использовать v.reserve(NewCapacity)
, чтобы вектор имел емкость не менее NewCapacity
.
Также помните, что когда вектор уничтожается, базовый массив также удаляется.
Ответ 2
int* pv = &v[0]
Обратите внимание, что это относится только к std::vector<>
, вы не можете сделать то же самое с другими стандартными контейнерами.
Скотт Мейерс широко освещал эту тему в своих книгах.
Ответ 3
В С++ 11 вы можете использовать vector:: data() для получения указателя массива C.
Ответ 4
Если у вас есть очень контролируемые условия, вы можете просто сделать:
std::vector<int> v(4,100);
int* pv = &v[0];
Будем предупреждать, что это будет работать только до тех пор, пока вектор не будет расти, и вектор все равно будет управлять временем жизни базового массива (то есть не удалять pv). Это не редкость делать при вызове базовых C API, но обычно это делается с неназванным временным, а не путем создания явной переменной int *.
Ответ 5
Один из способов защитить себя от изменений размера - это зарезервировать максимальное пространство (или больше), которое вам понадобится:
std::vector<int> v(4,100); //Maybe need
v.reserve(40); //reallocate to block out space for 40 elements
Это гарантирует, что push_backs не приведет к перераспределению существующих данных.