Les éléments vectoriels sont stockés contiguës, je suppose qu'il ne peut pas avoir la même adresse après que certains push_back's, car l'espace alloué initial ne pouvait pas suffire.
Je travaille sur un code où j'ai besoin d'une référence à un élément Dans un vecteur, comme: p> mais ce n'est pas nécessairement vrai que Ma première idée serait d'utiliser un vecteur de pointeurs et d'une allocation dynamique. Je me demande s'il y a un moyen plus facile de le faire? P> PS.: En fait, j'utilise un vecteur d'une classe au lieu d'INT, mais je pense que les problèmes sont les mêmes. p> p> PTR code> contient une référence à
V [0] code> , droit? Comment serait un bon moyen de le garantir? P>
8 Réponses :
Vous pouvez augmenter la capacité de la matrice sous-jacente utilisée par le vecteur en appelant son code> Fonction de membre code> Membre: tant que vous ne mettez pas plus que 100 éléments dans le vecteur, pTR code> pointeront sur le premier élément. P> p>
Étant donné que réserve code> se réserve au moins autant que vous demandez, vous pouvez mettre à la hauteur de la capacité
Capacité code> dans le vecteur.
Le problème est maintenant que je ne sais pas combien d'espace sera utilisé. Est-ce une bonne idée d'utiliser une valeur suffisamment élevée? Dans certains cas, seuls 10 ^ 6 seraient sûrs, mais dans d'autres cas, 100 suffiraient.
Si vous ne savez pas combien d'éléments vous allez stocker, vous réservez une mauvaise idée! Vous ne faites que reporter votre bogue de pointeur pendant plus tard, lorsque le vecteur dépasse cette capacité!
Si vous ne connaissez pas à l'avance combien d'éléments vous allez insérer, utilisez un index dans le conteneur ou un pointeur intelligent comme Jerry Coffin suggère.
Comment serait un bon moyen de le garantir? P> blockQuote>
std :: vecteur
code> est garanti d'être toujours continu, mais la mise en œuvre est libre de réaffecter ou de stockage libre sur les opérations altérant le contenu du vecteur (vecteurs itérateurs, points-points ou références aux éléments deviennent indéniables. aussi). P> Vous pouvez toutefois atteindre le résultat souhaité, cependant, en appelant
réserve code>. IIRC, la norme garantit qu'aucune réaffectation n'est effectuée jusqu'à ce que la taille du vecteur soit supérieure à sa capacité réservée. P>
Généralement, je ferais attention avec cela (vous pouvez être rapidement piégé ...). Mieux vaut ne pas compter sur
std :: vecteur <> :: réserve code> et itérateur persistance que si vous ne devez vraiment pas. P>
Comme James McNellis et Alexander Gessler ont déclaré, réserve code> est un bon moyen de pré-allouer de la mémoire. Cependant, pour l'exhaustivité, j'aimerais ajouter que les pointeurs doivent rester valables, toutes les opérations d'insertion / d'élimination doivent se produire de la queue du vecteur, sinon l'élément changeant invalidera à nouveau vos pointeurs. P>
L'invalidation dépendra de l'utilisation des pointeurs. Si int * pTR = & V [0]; code> est destiné à représenter un élément spécifique de la liste, puis oui, il pourrait être invalidé, mais s'il est destiné à représenter le premier élément de la liste, Quoi qu'il en soit, il ne sera pas invalidé.
Vous avez raison, bien sûr. J'ai supposé que le cas d'utilisation était de faire référence à un élément spécifique de la liste, car l'inverse est beaucoup plus facile à traiter de l'utilisation des méthodes à votre disposition pour récupérer des éléments à des indices spécifiques.
Selon vos besoins et votre cas d'utilisation, vous voudrez peut-être jeter un coup d'œil à Bibliothèque de conteneurs de pointeur de Boost . P>
Dans votre cas, vous pouvez utiliser boost :: pTR_Vector
Une autre possibilité de possibilité serait un pointeur intelligent construit à des fins qui, au lieu de stocker une adresse stockerait l'adresse du vecteur lui-même avec l'index de l'article que vous aimez. Il ne poserait alors ceux-ci et obtenez l'adresse de l'élément uniquement lorsque vous la déréférez, quelque chose comme ceci: alors votre Quelques points: Tout d'abord, si vous réorganisez les éléments de votre Vecteur entre le moment où vous créez le "pointeur" et le temps que vous avez la désarférence, il ne se référera plus à l'élément d'origine, mais à tout élément se produit à la position spécifiée. Deuxièmement, cela ne vérifie aucune plage, donc (par exemple) tenter d'utiliser l'élément 100 TH sup> dans un vecteur qui ne contient que 50 éléments donnera un comportement non défini. P> p> int * ptr = & v [0]; code> serait remplacé par quelque chose comme:
vec_ptr
Si vous n'avez pas besoin de vos valeurs stockées contiguës, vous pouvez utiliser std :: deque au lieu de std :: vecteur. Il ne réaffecte pas, mais contient des éléments dans plusieurs morceaux de mémoire. P>
ne faites pas em> réserve pour reporter ce bug de pointeur suspendu - comme une personne qui a eu le même problème, haussa les épaules, réservé 1000, puis quelques mois plus tard ont passé des âges à essayer de comprendre un bug de mémoire étrange (La capacité de vecteur dépassée 1000), je peux vous dire que ce n'est pas une solution robuste. P>
Vous voulez La meilleure solution consiste à changer votre conteneur: P>
Pointeurs avec New / Supprimer Présentez un problème lorsqu'un vecteur est détruit lorsque vous n'attendez pas cela - à cause d'une exception lancée par exemple.
IMO: STD :: La liste a très peu d'usages. Je recommanderais STD :: Deque à la place.
J'ai aussi rencontré ce problème et j'ai passé une journée entière juste pour réaliser l'adresse de vecteur modifiée et que les adresses enregistrées sont devenues invalides. Pour mon problème, ma solution était que p>
J'ai trouvé les travaux suivants p>
Cependant, je n'ai pas compris comment utiliser vector.front () et je ne suis pas sûr de savoir si je devrais utiliser Pointants [I] = indices [i] * Tailleof (Vector) + (taille_t) et vecteur [0]. Je pense que la manière de référence (2) devrait être très sûre. P>
Pourquoi ne pas obtenir
& v [0] code> uniquement lorsque vous en avez besoin?
Vous pouvez conserver l'index de l'élément au lieu du pointeur, puis pour y accéder à () ou opérateur []
@KennyTM Bien que: il n'est pas expliqué ci-dessus, dans mon code actuel, je ne peux plus dire quel index pour accéder quand j'en ai besoin.
@DMitry Yudakov: bonne idée! Malheureusement, j'ai réalisé que l'utilisation de cette approche vous obligerait à faire beaucoup de changements, car j'ai déjà utilisé une structure avec des pointeurs dans d'autres parties du code, mais sans problèmes puisque je préalcule le vecteur.