56 votes

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

Si vous avez un vecteur STL qui a été redimensionné, est-il sûr de prendre l'adresse de l'élément 0 et d'assumer que le reste du vecteur suivra en mémoire?

par exemple

vector vc(100);
// faites des choses avec vc
vc.resize(200);
char* p = &vc[0];
// faites des choses avec *p

72voto

Eclipse Points 27662

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

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

Les éléments d'un vecteur sont stockés contiguëment, ce qui signifie que si v est un vecteur où T est un type autre que bool, alors il respecte l'identité &v[n] == &v[0] + n pour tout 0 <= n < v.size().

(*) ... mais attention à la réallocation du tableau (invalidant ainsi tout pointeur et itérateur) après l'ajout d'éléments.

1 votes

Si vous utilisez une norme provisoire, ou tout ce qui n'est pas encore ratifié et officiel, veuillez le préciser. Je n'ai rien trouvé de tel dans la norme actuelle.

5 votes

Dans le brouillon de C++0x, c'est le 23.2.5.1, et dans C++03, c'est 23.2.4.1. Le libellé n'est pas dans la norme C++98. Je regarde ISO/IEC 14882:2003(E)

1 votes

Cela a été ajouté ultérieurement dans le Corrigendum technique.

27voto

Michael Burr Points 181287

La norme C++03 a ajouté des termes pour clarifier que les éléments de vector doivent être contigus.

Le paragraphe 1 de C++03 23.2.4 contient le langage suivant qui ne se trouve pas dans le document de la norme 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 satisfait l'identité &v[n] == &v[0] + n pour tous les 0 <= n < v.size().

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

... la contiguïté fait en fait partie de l'abstraction du vector. C'est tellement important, en fait, que lorsqu'il a été découvert que la norme C++98 ne garantissait pas complètement la contiguïté, la norme C++03 a été modifiée pour ajouter explicitement la garantie.

0 votes

+1: Ceci est la réponse. Il est seulement sûr de supposer puisque avec des implémentations conformes à 2003, pas "toujours".

14voto

Adam Points 2333

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 itérateur sur l'élément zéro (ou sur n'importe quel élément) avant une opération de modification de capacité, il est invalidé et doit être réassigné.

10voto

Jasper Bekkers Points 4949

4voto

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

&myVector.front();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X