7
votes

En C ++, la fonction vectorielle sera-t-elle push_back pour augmenter la taille d'un tableau vide?

Question rapide. Disons que je déclare un vecteur de taille 20. Et puis je voudrais ajouter quelques entiers à l'aide d'appuyer sur Push_back.

vector<int> myVector(20);
myVector.push_back(5);
myVector.push_back(14);


1 commentaires

N'hésitez pas à essayer ce vous-même .


6 Réponses :


1
votes

push_back augmente la taille du std :: vecteur et place les nouveaux éléments à l'arrière du vecteur (d'autres conteneurs ont également un push_front méthode pour faire la même chose à l'avant).

Cependant, il y a une différence entre la taille et la capacité d'un vecteur . La taille fait référence au nombre d'éléments dans le vecteur en ce moment; La capacité fait référence au nombre total d'éléments que le vecteur peut contenir sans mémoire de réaffectation. Il est possible de réserve () la mémoire si vous savez que vous allez ajouter plusieurs éléments et que vous ne voulez pas développer le vecteur fragameal.


2 commentaires

Ok, alors push_back n'augmente pas la capacité, non? Sauf si ce vecteur est déjà à pleine capacité.


Correct, cela n'augmente pas nécessairement la capacité. Je ne le mentionne que parce que std :: vecteur passe par la peine de faire la distinction afin qu'il soit important de garder les termes droites, surtout lors de la lecture de la documentation pour std :: vecteur .



1
votes

comme le vecteur n'est pas vide mais a une taille de 20 (contient 20 éléments) et vous appuyez sur 2 éléments sur le dos , Il contient maintenant 22 éléments. Mais les nouveaux éléments ne sont pas placés aux indices 19 et 20, mais 20 et 21.

Si vous voulez vraiment réserver suffisamment de mémoire pour le vecteur pour contenir 20 éléments (sans contenir réellement aucun élément), pour éviter les réaffectations coûteuses, Ensuite, vous devez appeler xxx

dans ce cas, le vecteur est toujours vide, mais il a suffisamment de mémoire pour ajouter au moins 20 éléments (en utilisant push_back , par exemple) sans avoir à réaffecter son stockage interne. Dans ce cas, le vecteur ne contient que les 2 éléments que vous poussez ed _back .


1 commentaires

Très utile, merci. Essentiellement ce que je veux faire, c'est créer un vecteur et ajouter uniquement des éléments à la fin. Cela ne m'a pas eu pour moi que je n'ai même pas besoin de donner une taille initialement, car les vecteurs sont dynamiques. Merci!



3
votes
  • Taille est le nombre d'éléments dans le conteneur de vecteur.
  • capacité est la taille de l'espace de stockage alloué
  • push_back augmente efficacement la taille du vecteur par un, ce qui provoque une réaffectation du stockage alloué interne si la taille du vecteur était égale à la capacité de vecteur avant l'appel.

    Plus d'info: http://www.cplusplus.com/reference/stl/vector/


0 commentaires

1
votes

Eh bien, vecteur a la fonction de membre push_back . Autres séquences telles que deque ont push_front .

0, 1, 2, ......, finale

Après addition:

0, 1, 2, ....., final, addition, ...

Vous pouvez vous rappeler que: xxx

c'est-à-dire, vous ne pouvez pas ajouter à l'avant ou au milieu, car le vecteur est spécialisé pour un accès rapide aux éléments par index. Si vous souhaitez ajouter à l'avant et à l'arrière, vous pouvez utiliser deque similaire à vecteur . Si vous souhaitez ajouter à l'avant, le dos et n'importe où vous pouvez utiliser list . Notez que liste ne fournit pas d'indexation comme deque et vecteur .

Cependant, un vecteur est supposé avoir plus capacité que sa taille réelle. Lorsque vous y ajoutez des éléments, il n'est pas nécessaire d'allouer de la mémoire supplémentaire. Cela ne fait que si la capacité est égale à la taille. Sur de nombreux compilateurs, la nouvelle capacité sera le double de l'ancien. Après allocation, il copie tous les éléments du nouvel emplacement. Un tel comportement peut toutefois être coûteux en termes de mémoire.


0 commentaires

1
votes

push_back augmentera la capacité du vecteur au moins la nouvelle taille du vecteur, mais éventuellement (c'est-à-dire probablement) quelque peu plus grande.

parce que push_back est requis pour exécuter dans O (1) du temps amorti, chaque réaffectation sera à un multiple de l'ancienne capacité. Dans une implémentation typique que multiple est 2.

Mais l'augmentation exacte de la capacité n'est pas spécifiée. Si vous avez besoin de contrôle précis sur la capacité, utilisez réserve .

...

Re-lisant votre question, je ne suis pas sûr de comprendre la différence entre la taille d'une vecteur et sa capacité. La taille est le nombre d'éléments. La capacité est le nombre d'éléments que le vecteur peut contenir sans effectuer une réaffectation. C'est-à-dire que vous pouvez push_back capacité () - taille () - taille () avant qu'une réaffectation ne se produise.

Dans votre exemple, 5 et 14 apparaîtront à myvector [20] et myvector [21], respectivement.


3 commentaires

À droite. Ce que je n'ai pas compris, c'est que les vecteurs ne nécessitent pas de capacité lorsqu'ils les créent, c'est qu'ils sont pointus - ils sont dynamiques, non? Donc, c'est une sorte d'inutile de leur donner une capacité initiale.


@IAACP: Non, ce n'est pas inutile. Si vous savez à l'avance, combien de choses vous envisagez de mettre à l'intérieur du vecteur, mais vous n'avez pas les choses réelles à portée de main lors de l'initialisation du vecteur, vous pouvez alors réserve () un montant de sorte que le Vecteur ne doit pas faire de réaffectation.


@IIACP: Ce n'est pas inutile si vous vous souciez réellement de réallocation. La réaffectation (A) prend du temps et (b) invalide les références / les pointeurs sur des éléments à l'intérieur du vecteur. Réservez Vous permet de définir la capacité pour éviter les rétroglocations futures. Notez que votre exemple définit la taille du vecteur, pas la capacité . Vous créez un vecteur de 20 entiers non initialisés.



16
votes

Après ces déclarations, sa capacité est définie par la mise en œuvre. (Veuillez noter que c'est différent de sa taille.)


xxx pré>

ceci crée un vecteur rempli de vingt ans. Sa taille est vingt, exactement et sa capacité est d'au moins vingt. Que ce soit ou non exactement vingt est défini par la mise en œuvre; Il peut avoir plus (probablement pas dans la pratique). p> xxx pré>

Après cela, le vingt-premier élément du tableau est 5, et la capacité est à nouveau définie par la mise en œuvre. . (Si la capacité avait été exactement vingt avant, elle est maintenant augmentée de manière non spécifiée.) P> xxx pré>

de même, le vingt-deuxième élément du tableau est de 14, et La capacité est définie par la mise en oeuvre. p>


Si vous souhaitez réserver de la place, mais ne pas insérer des éléments, vous le feriez comme ceci: P>

vector<int> myVector;
myVector.reserve(20); // capacity is at least twenty, guaranteed not
                      // to reallocate until after twenty elements are pushed

myVector.push_back(5); // at index zero, capacity at least twenty.
myVector.push_back(14); // at index one, capacity at least twenty.


2 commentaires

Notez que c ++ 03 standard 23.2.4 / 1 nécessite que vecteur S "support (amortizé) temps constant insertion et efface les opérations à la fin", donc dans la pratique. La capacité se développe généralement par un facteur de deux lorsque push_back () a besoin de plus de place.


Bien. Merci. Je ne savais pas que cela remplirait avec 20 0. Cela aurait vraiment foiré mon programme. Je ne sais pas pourquoi je ne pensais pas à ne pas préciser une taille, voyant comment ils sont dynamiques et c'est ce dont j'ai besoin. Un derp en mon nom.