¿Diferencia entre std :: resize (n) y std :: shrink_to_fit en C ++?

11

Me encontré con estas declaraciones:

resize(n)- Cambia el tamaño del contenedor para que contenga elementos 'n'.
shrink_to_fit()- Reduce la capacidad del contenedor para adaptarse a su tamaño y destruye todos los elementos más allá de la capacidad.

¿Hay alguna diferencia significativa entre estas funciones? vienen bajo vectores en c ++

Sneha Sridharan
fuente
redimensionar modifica el tamaño del contenedor, shrink_to_fit no. Para el uso normal, no necesita saber acerca de shrink_to_fit, solo está disponible para permitir que los desarrolladores aumenten manualmente el rendimiento de su código.
NoSenseEtAl
2
Los contenedores estándar tienen un tamaño y una capacidad . El tamaño es el número actual de elementos en el contenedor, mientras que la capacidad es la cantidad de memoria asignada (aproximadamente). Cambiar el tamaño cambia el tamaño, shrink_to_fitcambia la capacidad.
Algún tipo programador
2
¿Entiendes la diferencia entre capacityy size?
Cubic

Respuestas:

12

Los vectores tienen dos atributos de "longitud" que significan cosas diferentes:

  • sizees el número de elementos utilizables en el vector. Es la cantidad de cosas que has almacenado. Esta es una longitud conceptual.
  • capacity es cuántos elementos cabrían en la cantidad de memoria que el vector ha asignado actualmente.

capacity >= sizedebe ser siempre cierto, pero no hay razón para que sean siempre iguales. Por ejemplo, cuando elimina un elemento, reducir la asignación requeriría crear una nueva asignación un cubo más pequeño y mover el contenido restante ("asignar, mover, liberar").

De manera similar, si capacity == sizeagrega un elemento, el vector podría aumentar la asignación en un elemento (otra operación "asignar, mover, liberar"), pero generalmente agregará más de un elemento. Si la capacidad necesita aumentar, el vector aumentará su capacidad en más de un elemento para que pueda agregar varios elementos más antes de tener que mover todo nuevamente.

Con este conocimiento, podemos responder a su pregunta:

  • std::vector<T>::resize()cambia el tamaño de la matriz. Si cambia el tamaño más pequeño que su tamaño actual, los objetos en exceso se destruyen. Si cambia su tamaño por encima de su tamaño actual, los "nuevos" objetos agregados al final se inicializan por defecto.
  • std::vector<T>::shrink_to_fit()pide que se cambie la capacidad para que coincida con el tamaño actual. (Las implementaciones pueden o no cumplir con esta solicitud. Pueden disminuir la capacidad pero no igualarla al tamaño. Es posible que no hagan nada en absoluto.) Si la solicitud se cumple, esto descartará parte o la totalidad de la porción no utilizada de La asignación del vector. Por lo general, usaría esto cuando haya terminado de construir un vector y nunca le agregará otro elemento. (Si sabe de antemano cuántos elementos agregará, sería mejor usar std::vector<T>::reserve()para decir el vector antes de agregar cualquier elemento en lugar de confiar en shrink_to_fithacer algo).

Entonces usas resize()para cambiar la cantidad de cosas conceptualmente en el vector.

Se usa shrink_to_fit()para minimizar el exceso de espacio que el vector ha asignado internamente sin cambiar la cantidad de material que está conceptualmente en el vector.

cdhowie
fuente
2
Tenga en cuenta que shrink_to_fitno es todo o nada. Una implementación puede reducir la capacidad en parte. Por ejemplo, considere una implementación que restringe la capacidad del vector a potencias de dos.
François Andrieux
5

shrink_to_fit() - Reduce la capacidad del contenedor para adaptarse a su tamaño y destruye todos los elementos más allá de la capacidad.

Esa es una caracterización errónea de lo que sucede. En segundo lugar, la destrucción de todos los elementos más allá de la parte de capacidad no es precisa.

En C ++, cuando se usa dinámicamente memoria para objetos, hay dos pasos:

  1. Se asigna memoria para los objetos.
  2. Los objetos se inicializan / construyen en las ubicaciones de memoria.

Cuando se eliminan objetos en memoria asignada dinámicamente, también hay dos pasos, que reflejan los pasos de construcción pero en orden inverso:

  1. Objetos en las ubicaciones de memoria destruidos (para los tipos integrados, esto es un noop).
  2. La memoria utilizada por los objetos se desasigna.

La memoria asignada más allá del tamaño del contenedor es solo un búfer. No contienen ningún objeto inicializado correctamente. Es solo memoria cruda. shrink_to_fit()se asegura de que la memoria adicional no esté allí pero que no haya objetos en esas ubicaciones. Por lo tanto, no se destruye nada, solo se desasigna la memoria.

R Sahu
fuente
2

De acuerdo con el estándar C ++ relativo a shrink_to_fit

Efectos: shrink_to_fit es una solicitud no vinculante para reducir la capacidad () a tamaño ().

y relativo a resize

Efectos: si sz <size (), borra los últimos elementos size () - sz de la secuencia. De lo contrario, agrega elementos insertados por defecto sz - size () a la secuencia.

Es evidente que las funciones hacen cosas diferentes. Además, la primera función no tiene parámetro, mientras que la segunda función tiene incluso dos parámetros. La función shrink_to_fitno cambia el tamaño del contenedor, aunque puede reasignar la memoria.

Vlad de Moscú
fuente