Differenza tra std :: resize (n) e std :: shrink_to_fit in C ++?


11

Mi sono imbattuto in queste affermazioni:

resize(n)- Ridimensiona il contenitore in modo che contenga 'n' elementi.
shrink_to_fit()- Riduce la capacità del contenitore di adattarsi alle sue dimensioni e distrugge tutti gli elementi oltre la capacità.

C'è qualche differenza significativa tra queste funzioni? vengono sotto vettori in c ++


il ridimensionamento modifica la dimensione del contenitore, mentre shrink_to_fit no. Per un normale utilizzo non è necessario conoscere shrink_to_fit, è disponibile solo per consentire agli sviluppatori di aumentare manualmente le prestazioni del proprio codice.
NoSenseEtAl

2
I contenitori standard hanno una dimensione e una capacità . La dimensione è il numero corrente di elementi nel contenitore, mentre la capacità è la quantità di memoria allocata (approssimativamente). Il ridimensionamento modifica le dimensioni, shrink_to_fitmodifica la capacità.
Qualche programmatore, amico, il

2
Capisci la differenza tra capacitye size?
Cubico

Risposte:


12

I vettori hanno due attributi "lunghezza" che significano cose diverse:

  • sizeè il numero di elementi utilizzabili nel vettore. È il numero di cose che hai memorizzato. Questa è una lunghezza concettuale.
  • capacity è quanti elementi si adatteranno alla quantità di memoria che il vettore ha attualmente allocato.

capacity >= sizedeve essere sempre vero, ma non c'è motivo per cui siano sempre uguali. Ad esempio, quando si rimuove un elemento, la riduzione dell'allocazione richiederebbe la creazione di una nuova allocazione di un bucket più piccola e lo spostamento dei contenuti rimanenti ("allocazione, spostamento, libera").

Allo stesso modo, se capacity == sizee aggiungi un elemento, il vettore potrebbe aumentare l'allocazione di un elemento (un'altra operazione "alloca, sposta, libera"), ma di solito aggiungi più di un elemento. Se la capacità deve aumentare, il vettore aumenterà la sua capacità di più di un elemento in modo da poter aggiungere più altri elementi prima di dover spostare di nuovo tutto.

Con questa conoscenza, possiamo rispondere alla tua domanda:

  • std::vector<T>::resize()cambia la dimensione dell'array. Se lo ridimensioni più piccolo della sua dimensione attuale, gli oggetti in eccesso vengono distrutti. Se lo ridimensioni più grande della sua dimensione attuale, i "nuovi" oggetti aggiunti alla fine vengono inizializzati per impostazione predefinita.
  • std::vector<T>::shrink_to_fit()chiede che la capacità venga modificata in base alla dimensione corrente. (Le implementazioni possono o meno onorare questa richiesta. Potrebbero ridurre la capacità ma non renderla uguale alla dimensione. Potrebbero non fare nulla.) Se la richiesta viene soddisfatta, ciò eliminerà parte o tutta la parte non utilizzata di l'allocazione del vettore. In genere lo useresti quando hai finito di costruire un vettore e non aggiungerai mai un altro elemento. (Se sai in anticipo quanti elementi aggiungerai, sarebbe meglio usare std::vector<T>::reserve()per dire al vettore prima di aggiungere qualsiasi elemento invece di fare affidamento sul shrink_to_fitfare qualcosa.)

Quindi usi resize()per cambiare quanta roba è concettualmente nel vettore.

Si utilizza shrink_to_fit()per ridurre al minimo lo spazio in eccesso che il vettore ha allocato internamente senza modificare la quantità di materiale concettualmente presente nel vettore.


2
Nota che shrink_to_fitnon è tutto o niente. Un'implementazione può ridurre la capacità a metà strada. Ad esempio, prendere in considerazione un'implementazione che limiti la capacità del vettore a potenze di due.
François Andrieux, il

5

shrink_to_fit() - Riduce la capacità del contenitore di adattarsi alle sue dimensioni e distrugge tutti gli elementi oltre la capacità.

Questa è un'errata caratterizzazione di ciò che accade. In modo segreto, distrugge tutti gli elementi oltre la parte di capacità non è preciso.

In C ++, quando per gli oggetti viene utilizzata la memoria dinamicamente, esistono due passaggi:

  1. La memoria è allocata per gli oggetti.
  2. Gli oggetti vengono inizializzati / costruiti nelle posizioni di memoria.

Quando gli oggetti nella memoria allocata dinamicamente vengono eliminati, ci sono anche due passaggi, che rispecchiano i passaggi di costruzione ma in ordine inverso:

  1. Gli oggetti nelle posizioni di memoria sono stati distrutti (per i tipi integrati, questo è un noop).
  2. La memoria utilizzata dagli oggetti è deallocata.

La memoria allocata oltre la dimensione del contenitore è solo buffer. Non contengono oggetti correttamente inizializzati. È solo memoria grezza. shrink_to_fit()si assicura che la memoria aggiuntiva non sia presente ma non vi fossero oggetti in tali posizioni. Quindi, nulla viene distrutto, solo la memoria viene deallocata.


2

Secondo lo standard C ++ relativo a shrink_to_fit

Effetti: shrink_to_fit è una richiesta non vincolante per ridurre la capacità () a size ().

e relativo a resize

Effetti: se sz <size (), cancella gli ultimi elementi size () - sz dalla sequenza. Altrimenti, aggiunge alla sequenza sz - size () elementi inseriti per impostazione predefinita.

È evidente che le funzioni fanno cose diverse. Inoltre la prima funzione non ha parametri mentre la seconda funzione ha anche due parametri. La funzione shrink_to_fitnon modifica le dimensioni del contenitore sebbene possa riallocare la memoria.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.