Différence entre std :: resize (n) et std :: shrink_to_fit en C ++?

11

Je suis tombé sur ces déclarations:

resize(n)- Redimensionne le conteneur pour qu'il contienne des éléments «n».
shrink_to_fit()- Réduit la capacité du conteneur à s'adapter à sa taille et détruit tous les éléments au-delà de la capacité.

Y a-t-il une différence significative entre ces fonctions? ils relèvent de vecteurs en c ++

Sneha Sridharan
la source
resize modifie la taille du conteneur, ce qui n'est pas le cas pour shrink_to_fit. Pour une utilisation normale que vous n'avez pas besoin de connaître sur shrink_to_fit, il est uniquement disponible pour permettre aux développeurs d'augmenter manuellement les performances de leur code.
NoSenseEtAl
2
Les conteneurs standard ont une taille et une capacité . La taille est le nombre actuel d'éléments dans le conteneur, tandis que la capacité est la quantité de mémoire allouée (grosso modo). Le redimensionnement modifie la taille, shrink_to_fitmodifie la capacité.
Un programmeur mec le
2
Comprenez-vous la différence entre capacityet size?
Cubic

Réponses:

12

Les vecteurs ont deux attributs de "longueur" qui signifient différentes choses:

  • sizeest le nombre d'éléments utilisables dans le vecteur. C'est le nombre de choses que vous avez stockées. Il s'agit d'une longueur conceptuelle.
  • capacity est le nombre d'éléments qui correspondraient à la quantité de mémoire que le vecteur a actuellement allouée.

capacity >= sizedoit toujours être vrai, mais il n'y a aucune raison pour qu'ils soient toujours égaux. Par exemple, lorsque vous supprimez un élément, la réduction de l'allocation nécessite la création d'une nouvelle allocation d'un compartiment plus petit et le déplacement du contenu restant ("allouer, déplacer, libérer").

De même, si capacity == sizeet vous ajoutez un élément, le vecteur pourrait augmenter l'allocation d'un élément (une autre opération "allouer, déplacer, libérer"), mais généralement vous allez ajouter plus d'un élément. Si la capacité doit augmenter, le vecteur augmentera sa capacité de plus d' un élément afin que vous puissiez ajouter plusieurs autres éléments avant de devoir tout déplacer à nouveau.

Avec ces connaissances, nous pouvons répondre à votre question:

  • std::vector<T>::resize()modifie la taille du tableau. Si vous le redimensionnez plus petit que sa taille actuelle, les objets en excès sont détruits. Si vous le redimensionnez plus grand que sa taille actuelle, les "nouveaux" objets ajoutés à la fin sont initialisés par défaut.
  • std::vector<T>::shrink_to_fit()demande que la capacité soit modifiée pour correspondre à la taille actuelle. (Les implémentations peuvent ou non honorer cette demande. Elles peuvent réduire la capacité mais pas la rendre égale à la taille. Elles peuvent ne rien faire du tout.) l'allocation du vecteur. Vous l'utiliseriez généralement lorsque vous aurez terminé de créer un vecteur et n'y ajouterez jamais d'autre élément. (Si vous savez à l'avance combien d'éléments vous ajouterez, il serait préférable d'utiliser std::vector<T>::reserve()pour indiquer le vecteur avant d'ajouter des éléments au lieu de compter sur shrink_to_fitquoi que ce soit.)

Vous utilisez donc resize()pour modifier la quantité de contenu conceptuel dans le vecteur.

Vous utilisez shrink_to_fit()pour minimiser l'espace excédentaire que le vecteur a alloué en interne sans modifier la quantité conceptuelle du vecteur.

cdhowie
la source
2
Notez que ce shrink_to_fitn'est pas tout ou rien. Une implémentation peut réduire la capacité à mi-chemin. Par exemple, considérons une implémentation qui contraint la capacité vectorielle à des puissances de deux.
François Andrieux
5

shrink_to_fit() - Réduit la capacité du conteneur à s'adapter à sa taille et détruit tous les éléments au-delà de la capacité.

C'est une mauvaise description de ce qui se passe. Plus précisément, le détruit tous les éléments au-delà de la partie capacité n'est pas précis.

En C ++, lorsque la mémoire est utilisée dynamiquement pour les objets, il y a deux étapes:

  1. La mémoire est allouée aux objets.
  2. Les objets sont initialisés / construits aux emplacements de mémoire.

Lorsque des objets dans la mémoire allouée dynamiquement sont supprimés, il y a également deux étapes, qui reflètent les étapes de construction mais dans l'ordre inverse:

  1. Objets détruits aux emplacements de mémoire (pour les types intégrés, il s'agit d'un noop).
  2. La mémoire utilisée par les objets est désallouée.

La mémoire allouée au-delà de la taille du conteneur n'est qu'un tampon. Ils ne contiennent aucun objet correctement initialisé. C'est juste de la mémoire brute. shrink_to_fit()s'assure que la mémoire supplémentaire n'est pas là mais qu'il n'y avait aucun objet dans ces emplacements. Par conséquent, rien n'est détruit, seule la mémoire est désallouée.

R Sahu
la source
2

Selon la norme C ++ relative à shrink_to_fit

Effets: shrink_to_fit est une demande non contraignante pour réduire la capacité () à la taille ().

et par rapport à resize

Effets: Si sz <size (), efface les derniers éléments size () - sz de la séquence. Sinon, ajoute à la séquence les éléments insérés par défaut sz - size ().

Il est évident que les fonctions font des choses différentes. De plus, la première fonction n'a pas de paramètre tandis que la deuxième fonction a même deux paramètres. La fonction shrink_to_fitne modifie pas la taille du conteneur mais peut réallouer de la mémoire.

Vlad de Moscou
la source