web-dev-qa-db-fra.com

Conversion entre C++ std :: vector et C array sans copier

J'aimerais pouvoir convertir entre std :: vector et son tableau C sous-jacent int * sans copier explicitement les données. 

Std :: vector fournit-il un accès au tableau C sous-jacent? Je cherche quelque chose comme ça 

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

MODIFIER:

Aussi, est-il possible de faire l’inverse, c’est-à-dire comment initialiser un std::vector à partir d’un tableau C sans copier?

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

Vous pouvez obtenir un pointeur sur le premier élément comme suit:

int* pv = &v[0];

Ce pointeur n'est valide que tant que le vecteur n'est pas réaffecté. La réallocation est automatique si vous insérez plus d'éléments que ne le permet la capacité restante du vecteur (c'est-à-dire si v.size() + NumberOfNewElements > v.capacity(). Vous pouvez utiliser v.reserve(NewCapacity) pour vous assurer que le vecteur a une capacité d'au moins NewCapacity.

Rappelez-vous également que lorsque le vecteur est détruit, le tableau sous-jacent est également supprimé.

80
James McNellis
int* pv = &v[0]

Notez que ce n'est que le cas pour std::vector<>, vous ne pouvez pas faire la même chose avec d'autres conteneurs standard.

Scott Meyers couvre ce sujet de manière approfondie dans ses livres.

19
Ðаn

Dans c ++ 11, vous pouvez utiliser vector :: data () pour obtenir un pointeur de tableau C.

19
m.elahi

Si vous avez des conditions très contrôlées, vous pouvez simplement faire:

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

Soyez averti que cela ne fonctionnera que tant que le vecteur n'aura pas à grandir et qu'il gèrera toujours la durée de vie du tableau sous-jacent (c'est-à-dire, ne supprimez pas pv). Ce n'est pas une chose rare à faire lorsque vous appelez des API C sous-jacentes, mais cela se fait généralement avec un temporaire non nommé plutôt que de créer une variable int * explicite.

15
Drew Hall

Une façon de vous protéger contre les changements de taille consiste à réserver l'espace maximal (ou supérieur) dont vous aurez besoin:

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

Cela garantira que Push_backs ne provoquera pas de réallocation des données existantes.

0
user1270710