391 votes

std::vector versus std::array en C++

Quelle est la différence entre un std::vector et un std::array en C++ ? Quand faut-il en préférer un à un autre ? Quels sont les avantages et les inconvénients de chacun ? Tout ce que fait mon manuel, c'est énumérer comment ils sont identiques.

2 votes

Je cherche une comparaison entre std::vector vs. std::array et comment les termes sont différents.

1 votes

Zud, std::array n'est pas la même chose qu'un tableau C++. std::array est une enveloppe très fine autour des tableaux C++, dont le but principal est de cacher le pointeur à l'utilisateur de la classe. Je vais mettre à jour ma réponse.

0 votes

J'ai mis à jour le titre et le texte de la question pour refléter votre clarification.

413voto

Matteo Italia Points 53117

std::vector est une classe template qui encapsule un tableau dynamique 1 stockée dans le tas, qui croît et décroît automatiquement si des éléments sont ajoutés ou supprimés. Il fournit tous les crochets ( begin() , end() , itérateurs, etc.) qui lui permettent de fonctionner correctement avec le reste de la STL. Il dispose également de plusieurs méthodes utiles qui vous permettent d'effectuer des opérations qui, sur un tableau normal, seraient fastidieuses, comme par exemple l'insertion d'éléments au milieu d'un vecteur (il gère tout le travail de déplacement des éléments suivants en coulisse).

Comme il stocke les éléments dans la mémoire allouée sur le tas, il présente une certaine surcharge par rapport aux tableaux statiques.

std::array est une classe modèle qui encapsule un tableau de taille statique, stocké dans l'objet lui-même, ce qui signifie que, si vous instanciez la classe sur la pile, le tableau lui-même sera sur la pile. Sa taille doit être connue au moment de la compilation (elle est passée en tant que paramètre de modèle), et il ne peut ni croître ni décroître.

C'est plus limité que std::vector mais il est souvent plus efficace, surtout pour les petites tailles, car en pratique, il s'agit surtout d'un emballage léger autour d'un tableau de style C. Cependant, il est plus sûr, puisque la conversion implicite en pointeur est désactivée, et il fournit une grande partie des fonctionnalités liées à la STL de std::vector et des autres conteneurs, de sorte que vous pouvez l'utiliser facilement avec les algorithmes STL & co. Quoi qu'il en soit, pour la seule limitation de la taille fixe, il est bien moins flexible que std::vector .

Pour une introduction à std::array Jetez un coup d'œil à cet article ; pour une introduction rapide à std::vector et aux opérations qu'il est possible d'effectuer sur lui, vous pouvez regarder son documentation .


  1. En fait, je pense que dans la norme, ils sont décrits en termes de complexité maximale des différentes opérations (par exemple, accès aléatoire en temps constant, itération sur tous les éléments en temps linéaire, ajout et retrait d'éléments à la fin en temps constant amorti, etc.), mais je ne connais pas d'autre méthode pour répondre à ces exigences que d'utiliser un tableau dynamique. Comme indiqué par @Lucretiel, la norme exige en fait que les éléments soient stockés de manière contiguë, donc c'est un tableau dynamique, stocké là où l'allocateur associé le place.

8 votes

Concernant votre note de bas de page : Bien que cela soit vrai, la norme garantit également que l'arithmétique des pointeurs sur les éléments internes fonctionne, ce qui signifie qu'il doit s'agir d'un tableau : &vec[9] - &vec[3] == 6 est vrai.

11 votes

Je suis presque sûr que le vecteur ne se réduit pas automatiquement, mais depuis C++11 vous pouvez appeler shrink_to_fit.

1 votes

Je suis totalement confus par le terme tableau statique et je ne suis pas sûr de la bonne terminologie. Vous voulez dire un tableau de taille statique et non un tableau de variables statiques (un tableau utilisant un stockage statique). stackoverflow.com/questions/2672085/ . Quelle est la terminologie correcte ? Le terme "tableau statique" est-il un terme inapproprié pour désigner un tableau de taille fixe ?

21voto

ClosureCowboy Points 5023

Utilisation de la std::vector<T> classe :

  • ...est aussi vite que l'utilisation de tableaux intégrés, en supposant que vous ne fassiez que les choses que les tableaux intégrés vous permettent de faire (lire et écrire sur les éléments existants).

  • ...redimensionne automatiquement lorsque de nouveaux éléments sont insérés.

  • ...vous permet d'insérer de nouveaux éléments au début o au milieu du vecteur, en "décalant" automatiquement le reste des éléments vers le haut (est-ce que cela a un sens ?). Il vous permet de supprimer des éléments n'importe où dans le std::vector aussi, ce qui a pour effet de déplacer automatiquement le reste des éléments vers le bas.

  • ...vous permet d'effectuer une lecture vérifiée de la gamme avec le at() (vous pouvez toujours utiliser les indexeurs [] si vous ne voulez pas que cette vérification soit effectuée).

Il y a deux std::vector<T> :

  1. Vous n'avez pas d'accès fiable au pointeur sous-jacent, qui puede peut être un problème si vous avez affaire à des fonctions tierces qui demandent l'adresse d'un tableau.

  2. Le site std::vector<bool> La classe est idiote. Elle est implémentée comme un champ de bits condensé, pas comme un tableau. Évitez-la si vous voulez un tableau de bool s !

  3. Pendant l'utilisation, std::vector<T> vont être un peu plus grands qu'un tableau C++ avec le même nombre d'éléments. Cela est dû au fait qu'ils doivent garder la trace d'une petite quantité d'autres informations, comme leur taille actuelle, et parce que chaque fois que le tableau std::vector<T> s redimensionnent, ils réservent plus d'espace que nécessaire. Cela leur évite de devoir redimensionner à chaque fois qu'un nouvel élément est inséré. Ce comportement peut être modifié en fournissant un paramètre personnalisé allocator mais je n'ai jamais ressenti le besoin de le faire !


Edit : Après avoir lu la réponse de Zud à la question, j'ai pensé que je devais ajouter ceci :

Le site std::array<T> n'est pas la même chose qu'un tableau C++. std::array<T> est une enveloppe très fine autour des tableaux C++, dont le but principal est de cacher le pointeur à l'utilisateur de la classe (en C++, les tableaux sont implicitement convertis en pointeurs, souvent avec un effet consternant). Le site std::array<T> La classe stocke également sa taille (longueur), ce qui peut être très utile.

9 votes

C'est "aussi rapide" que d'utiliser un tableau intégré alloué dynamiquement. D'un autre côté, l'utilisation d'un tableau automatique peut avoir des performances considérablement différentes (et pas seulement pendant l'allocation, à cause des effets de localité).

8 votes

Pour les vecteurs non-bools en C++11 et plus, vous pouvez appeler data() sur un std::vector<T> pour obtenir le pointeur sous-jacent. Vous pouvez aussi simplement prendre l'adresse de l'élément 0 (fonctionnement garanti avec C++11, fonctionnera probablement avec les versions antérieures).

1 votes

Dans le dernier paragraphe, vous parlez de tableau C ? N'est-ce pas ?

2voto

Ian Bishop Points 3413

Un vecteur est en fait une enveloppe autour d'un tableau. Les tableaux ne sont pas des objets mais plutôt une représentation de la mémoire allouée. Un vecteur alloue une quantité fixe de mémoire (un tableau), ce qui vous permet d'ajouter et de supprimer des éléments facilement. Lorsque vous avez ajouté suffisamment d'éléments pour remplir le tableau du vecteur, celui-ci crée un nouveau tableau deux fois plus grand, en déplaçant chaque élément de l'ancien tableau vers le nouveau. Tout cela se passe en coulisses dans la classe Vector.

Utilisez des tableaux chaque fois que vous savez que vous avez une longueur fixe et que vous n'avez pas l'intention de modifier cette longueur. Sinon, utilisez un vecteur. Un vecteur présente l'avantage de disposer de méthodes pratiques telles que l'ajout et la suppression d'éléments en toute simplicité. Cependant, lorsque votre vecteur atteint sa taille maximale, il doit augmenter sa taille (par 2) et déplacer tous les éléments. Il s'agit d'une opération O(n), où n est le nombre d'éléments de votre vecteur (plutôt lent).

En outre, votre vecteur aura toujours de l'espace inutilisé. Bien que cela n'ait généralement pas d'importance, c'est un avantage d'un tableau avec une longueur fixe.

-12voto

tech_boy Points 15

L'un des avantages des vecteurs par rapport aux tableaux est qu'il est possible de trouver le taille actuelle d'un vecteur en utilisant nom_vectoriel.taille() .

Comme vous pouvez l'imaginer, cela peut être très utile dans de nombreuses situations, où vous pouvez facilement récupérer le nombre d'éléments dans la liste du tableau.

-19voto

Saif al Harthi Points 2173

Un vecteur est une classe conteneur tandis qu'un tableau est une mémoire allouée.

27 votes

Votre réponse semble aborder std::vector<T> contre T[] mais la question porte sur std::vector<T> contre std::array<T> .

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