Подтвердить что ты не робот

Преобразование между С++ 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);
4b9b3361

Ответ 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 не приведет к перераспределению существующих данных.