¿Hay alguna manera de cambiar el tamaño de un std :: vector para reducir la capacidad cuando ya no necesito espacio reservado anteriormente?Cómo reducir el tamaño de std :: vector?
Respuesta
STL efectivo, por Scott Meyers, artículo 17: utilice el truco swap
para recortar el exceso de capacidad.
vector<Person>(persons).swap(persons);
Después de eso, persons
es "escalada para ajustarse".
Esto se basa en el hecho de que el constructor de copias vector
asigna solo la cantidad de memoria necesaria para los elementos que se copian.
Crea un vector nuevo, temporal, del existente, luego llama al método de intercambio en el existente, pasando el temporal en. Deja que el temporal (ahora con el antiguo, sobredimensionado, buffer) salga del alcance.
Hey presto, su vector tiene exactamente el tamaño correcto para su contenido.
Si esto suena como una gran cantidad de copia y asignación, tenga en cuenta que esto es lo que hace el vector cada vez que tiene realloc más allá de su límite reservado actual de todos modos.
[Editar] Sí, acabo de decir lo mismo que Sebastien en más palabras. Otro caso de stackoverflow raza-condición ;-)
Bueno, te subí a Phil porque tu respuesta aún es útil, ¡incluso si no fuiste el primero en publicarla! :-) –
Heh, gracias Onorio – philsquared
Está buscando un equivalente de QVector::squeeze y me temo que no existe explícitamente en el STL. Busque la respuesta de Sébastien si es correcta para su implementación de STL.
Si está utilizando C++ 11, puede usar vec.shrink_to_fit()
. En VS2010 al menos, eso hace el truco de intercambio para usted.
No es equivalente al truco de intercambio. 'shrink_to_fit' es una solicitud no vinculante y no permite hacer nada. –
Dije "en VS2010" pero sí, en otros compiladores puede que no lo haga. –
@CatPlusPlus 'shrink_to_fit' hará con toda probabilidad el truco de intercambio o' realloc', pero con una pequeña optimización vectorial que aún no restablecerá 'capacity()' para que coincida con 'size()' porque no hay asignación de montón para reducir . Creo que esa es la razón por la que se especifica como "no vinculante". – Potatoswatter
El truco de intercambio es una manera eficaz de reducir la capacidad de un objeto, se intercambia el contenido de mi vector con un recién creado por la construcción de copia:
vector<Person>(persons).swap(persons);
en cuenta que no hay ninguna garantía de que personas.capacidad(); después del truco de intercambio es igual a el tamaño: la capacidad del vector (personas) es la capacidad que la implementación de la biblioteca reserva a los vectores de tamaño persons.size().
C++ 11 introducido shrink_to_fit().
shrink_to_fit() así como el truco de intercambio no garantiza que el tamaño de la capacidad sea efectivamente reducido al tamaño del vector.
Anyway shrink_to_fit() puede invalidar sus iteradores (si ocurre una reasignación) o no puede hacerlo: depende de la implementación real de la biblioteca.
Tenga en cuenta que el truco de intercambio requiere person.size() copiar construcciones de Person y person.size() destructions. El shrink_to_fit() podría evitar toda esta copia y podría dejar los iteradores válidos. Podría. Pero de vez en cuando sucede que shrink_to_fit() se implementa en términos del truco de intercambio ...
¿Podría indicar dónde se especifica que 'shrink_to_fit()' debe implementarse en términos de 'swap()'? –
@TobySpeight gracias por la observación. Quizás mi inglés no sea lo suficientemente bueno. Quise decir que dado que _shrink_to_fit() _ puede implementarse en términos del truco de intercambio, a veces se implementa de esta manera. Déjame editar la respuesta. Si no tengo éxito, siéntase libre de editar la respuesta para mejorar su calidad. Su contribución sería bienvenida. Gracias – jimifiki
- 1. tamaño de arreglo (bloqueo) de std :: vector
- 2. ¿Cómo funciona C++ std :: vector?
- 3. Cómo exportar std :: vector
- 4. Vector de tamaño constante
- 5. cómo reducir el tamaño de UIImage ...?
- 6. sizeof() std :: vector (C++)
- 7. C++ std :: pair, std :: vector y memcopy
- 8. std :: vector de funciones
- 9. std :: vector de std :: vectores de contigüidad
- 10. reducir la capacidad de un vector stl
- 11. std :: vector redimensionar hacia abajo
- 12. paso eficiente de std :: vector
- 13. ¿Puede un std :: vector ser = 'd a otro std :: vector?
- 14. ¿Cómo "mirar" el tamaño de un C++ std :: vector en gdb?
- 15. std :: vector versus std :: array en C++
- 16. ¿Cómo hacer std :: vector de otro vector con filtro específico?
- 17. vector con tamaño constante
- 18. std :: vector insert() reasignación
- 19. Borrar el rango de un std :: vector?
- 20. Reducir el tamaño del archivo de pdf
- 21. Reducir el tamaño de la imagen C#
- 22. std :: elementos de vector inicializando
- 23. Iterar std :: vector múltiple
- 24. std :: list vs std :: vector iteration
- 25. std :: merge fusionando dos std :: vector coredump
- 26. Vector claro frente a cambiar el tamaño
- 27. std :: vector <std::string> crash
- 28. Reducir el tamaño del repositorio git
- 29. ¿Es seguro el hilo std :: vector o boost :: vector?
- 30. ¿Cómo puedo ordenar un std :: vector por los valores de un std :: vector diferente?
Sugerir una corrección a la gramática: 'shrunked', no 'shrinked' –
Nice.¿Sabes quizás por qué no implementaron esto como método, ya que parece un caso de uso común para el contenedor? – bombardier
Una vez que el vector ha asignado un búfer, es difícil eliminar [] el final de ese búfer. Y hacerlo simplemente garantiza que las inserciones futuras requerirán la asignación de un nuevo buffer y la copia de todo (invalidación de iteradores). –