Est-il sûr de supposer que le stockage vectoriel STL est toujours contigu?

Si vous avez un vecteur STL qui a été redimensionné, est-il prudent de prendre l’adresse de l’élément 0 et de supposer que le rest du vecteur suivra en mémoire?

par exemple

vector vc(100); // do some stuff with vc vc.resize(200); char* p = &vc[0]; // do stuff with *p 

Oui, c’est une hypothèse valide (*).

A partir de la norme C ++ 03 (23.2.4.1):

Les éléments d’un vecteur sont stockés de manière contiguë, ce qui signifie que si v est un vecteur où T est un autre type que bool, alors il obéit à l’identité & v [n] == & v [0] + n pour tout 0 <= n

(*) … mais faites attention à la réallocation du tableau (invalidation des pointeurs et des iterators) après lui avoir ajouté des éléments.

La norme C ++ 03 a ajouté un libellé précisant que les éléments vectoriels doivent être contigus.

C ++ 03 23.2.4 Le paragraphe 1 contient le langage suivant qui ne figure pas dans le document standard C ++ 98:

Les éléments d’un vector sont stockés de manière contiguë, ce qui signifie que si v est un vectorT est un type autre que bool , alors il obéit à l’identité &v[n] == &v[0] + n pour tous 0 <= n < v.size() .

Herb Sutter parle de ce changement dans l'une de ses entrées de blog, Cringe not: Les vecteurs sont garantis d'être contigus :

... la contiguïté fait en effet partie de l'abstraction vectorielle. En fait, il est si important que lorsque l'on a découvert que la norme C ++ 98 ne garantissait pas totalement la continuité, la norme C ++ 03 a été modifiée pour append explicitement la garantie.

Le stockage est toujours contigu, mais il peut se déplacer lorsque la capacité du vecteur est modifiée.

Si vous aviez un pointeur, une référence ou un iterator sur l’élément zéro (ou un élément quelconque) avant une opération de modification de capacité, il est invalidé et doit être réaffecté.

Oui c’est contigu

std::vector garantit que les éléments sont stockés dans un tableau contigu, ce qui en fait le remplacement préféré des tableaux et peut également être utilisé pour s’interfacer avec du code de bas niveau dépendant de la plate-forme (comme les appels API Win32). Pour obtenir un pointeur sur le tableau, utilisez:

 &myVector.front(); 

Oui.

il devrait toujours être contigu