Diferença entre std :: resize (n) e std :: shrink_to_fit em C ++?

11

Me deparei com estas declarações:

resize(n)- Redimensiona o contêiner para que ele contenha elementos 'n'.
shrink_to_fit()- Reduz a capacidade do contêiner para caber em seu tamanho e destrói todos os elementos além da capacidade.

Existe alguma diferença significativa entre essas funções? eles vêm sob vetores em c ++

Sneha Sridharan
fonte
redimensionar modifica o tamanho do contêiner, shrink_to_fit não. Para uso normal que você não precisa conhecer sobre o shrink_to_fit, ele está disponível apenas para permitir que os desenvolvedores aumentem manualmente o desempenho de seu código.
NoSenseEtAl
2
Os contêineres padrão têm tamanho e capacidade . O tamanho é o número atual de elementos no contêiner, enquanto a capacidade é a quantidade de memória alocada (aproximadamente). Redimensionar altera o tamanho, shrink_to_fitaltera a capacidade.
Algum programador
2
Você entende a diferença entre capacitye size?
cúbico

Respostas:

12

Os vetores têm dois atributos "comprimento" que significam coisas diferentes:

  • sizeé o número de elementos utilizáveis ​​no vetor. É o número de coisas que você armazenou. Este é um comprimento conceitual.
  • capacity é quantos elementos caberiam na quantidade de memória que o vetor alocou atualmente.

capacity >= sizedeve sempre ser verdade, mas não há razão para que sejam sempre iguais. Por exemplo, quando você remove um elemento, reduzir a alocação exigiria a criação de uma nova alocação um depósito menor e a movimentação do conteúdo restante ("alocar, mover, livre").

Da mesma forma, se capacity == sizevocê adicionar um elemento, o vetor poderá aumentar a alocação em um elemento (outra operação "alocar, mover, liberar"), mas geralmente você adicionará mais de um elemento. Se a capacidade precisar aumentar, o vetor aumentará sua capacidade em mais de um elemento, para que você possa adicionar vários outros elementos antes de precisar mover tudo novamente.

Com esse conhecimento, podemos responder à sua pergunta:

  • std::vector<T>::resize()altera o tamanho da matriz. Se você o redimensionar menor que o tamanho atual, os objetos em excesso serão destruídos. Se você redimensioná-lo maior que seu tamanho atual, os "novos" objetos adicionados no final serão inicializados por padrão.
  • std::vector<T>::shrink_to_fit()solicita que a capacidade seja alterada para corresponder ao tamanho atual. (As implementações podem ou não atender a essa solicitação. Elas podem diminuir a capacidade, mas não torná-la igual ao tamanho. Elas podem não fazer nada.) Se a solicitação for atendida, isso descartará parte ou toda a parte não utilizada do alocação do vetor. Você usaria isso normalmente quando terminar de construir um vetor e nunca adicionará outro item a ele. (Se você souber com antecedência quantos itens você estará adicionando, seria melhor usar std::vector<T>::reserve()para informar o vetor antes de adicionar qualquer item, em vez de confiar em shrink_to_fitfazer qualquer coisa.)

Então você usa resize()para alterar a quantidade de coisas conceitualmente no vetor.

Você usa shrink_to_fit()para minimizar o excesso de espaço que o vetor alocou internamente, sem alterar a quantidade conceitual de coisas no vetor.

cdhowie
fonte
2
Observe que shrink_to_fitnão é tudo ou nada. Uma implementação pode reduzir a capacidade parcialmente. Por exemplo, considere uma implementação que restrinja a capacidade de vetores a potências de dois.
François Andrieux 25/02
5

shrink_to_fit() - Reduz a capacidade do contêiner para caber em seu tamanho e destrói todos os elementos além da capacidade.

Isso é uma descaracterização do que acontece. Em particular, a destruição de todos os elementos além da parte da capacidade não é precisa.

No C ++, quando a memória é usada dinamicamente para objetos, há duas etapas:

  1. A memória é alocada para objetos.
  2. Os objetos são inicializados / construídos nos locais de memória.

Quando objetos na memória alocada dinamicamente são excluídos, também existem duas etapas, que refletem as etapas de construção, mas em ordem inversa:

  1. Objetos nos locais de memória destruídos (para tipos internos, isso é um problema).
  2. A memória usada pelos objetos é desalocada.

A memória alocada além do tamanho do contêiner é apenas buffer. Eles não contêm nenhum objeto inicializado corretamente. É apenas memória bruta. shrink_to_fit()garante que a memória adicional não esteja lá, mas não haja objetos nesses locais. Portanto, nada é destruído, apenas a memória é desalocada.

R Sahu
fonte
2

De acordo com o padrão C ++ relativo a shrink_to_fit

Efeitos: shrink_to_fit é uma solicitação não vinculativa para reduzir a capacidade () ao tamanho ().

e em relação a resize

Efeitos: Se sz <size (), apaga os últimos elementos size () - sz da sequência. Caso contrário, anexa os elementos inseridos por padrão sz - size () à sequência.

É evidente que as funções fazem coisas diferentes. Além disso, a primeira função não possui parâmetro, enquanto a segunda função possui até dois parâmetros. A função shrink_to_fitnão altera o tamanho do contêiner, mas pode realocar a memória.

Vlad de Moscou
fonte