In che modo aggiungere e rimuovere elementi "ridimensiona" i dati? Come viene calcolata la dimensione del vettore (credo che sia tenuto traccia di)? Sarebbe gradita qualsiasi altra risorsa aggiuntiva per conoscere i vettori.Come funziona C++ std :: vector?
risposta
In termini di dimensionamento, ci sono due valori di interesse per un std::vector
: size
e capacity
(accessibile tramite .size()
e .capacity()
).
.size()
è il numero di elementi contenuti nel vettore, mentre .capacity()
è il numero di elementi che possono essere aggiunti al vettore, prima che la memoria venga riallocata.
Se si .push_back()
un elemento, la dimensione aumenterà di uno, fino a quando non si raggiunge la capacità. Una volta raggiunta la capacità, la maggior parte (tutte?) Le implementazioni, riallocare la memoria, raddoppiando la capacità.
È possibile prenotare una capacità utilizzando .riservare. Ad esempio:
std::vector<int> A;
A.reserve(1); // A: size:0, capacity:1 {[],x}
A.push_back(0); // A: size:1, capacity:1 {[0]}
A.push_back(1); // A: size:2, capacity:2 {[0,1]}
A.push_back(2); // A: size:3, capacity:4 {[0,1,2],x}
A.push_back(3); // A: size:4, capacity:4 {[0,1,2,3]}
A.push_back(4); // A: size:5, capacity:8 {[0,1,2,3,4],x,x,x}
Riassegnazioni di memoria si verificherebbe a linee 4, 5 e 7.
Ho scritto un vettore in C++ un anno fa. Si tratta di un array con una dimensione impostata (ad esempio 16 caratteri) che viene espansa di tale importo quando necessario. Vale a dire, se la dimensione predefinita è di 16 caratteri e occorre memorizzare Hi my name is Bobby
, raddoppierà la dimensione dell'array a 32 caratteri, quindi memorizzerà l'array di caratteri.
Il vettore ha solitamente tre puntatori. Se il vettore non è mai stato utilizzato, sono tutti 0 o NULL.
- Uno al primo elemento del vettore. (Questo è l'inizio() iterator)
- Soltanto all'ultimo elemento del vettore + 1. (questa è la fine() iterator)
- E un'altra all'ultima assegnato ma elemento inutilizzato + 1. (questo meno iniziale() è la capacità)
Quando un elemento viene inserito, il vettore assegna un po 'di spazio e imposta i puntatori. Potrebbe allocare 1 elemento o allocare 4 elementi. Oppure 50.
Quindi inserisce l'elemento e incrementa il puntatore dell'ultimo elemento.
Quando si inseriscono più elementi di quelli allocati, il vettore deve ottenere più memoria. Si spegne e ne prende un po '. Se la posizione della memoria cambia, deve copiare tutti gli elementi nel nuovo spazio e liberare il vecchio spazio.
Una scelta comune per il ridimensionamento è raddoppiare l'allocazione ogni volta che è necessario più memoria.
+1, non solo il raddoppio della memoria è un modello comune, ma è "obbligatorio" (\ *) per soddisfare l'inserimento e la cancellazione * a tempo costante ammortizzato alla fine *. (\ *) il raddoppio non è richiesto, ma la crescita esponenziale è. –
L'implementazione di std::vector
è leggermente cambiata con C++ 0x e in seguito con l'introduzione della semantica di spostamento (vedere What are move semantics? per un'introduzione).
Quando si aggiunge un elemento in un std::vector
che è già pieno allora il vector
viene ridimensionato che comporta una procedura di assegnazione di un nuovo, più grande area di memoria, spostando i dati esistenti al nuovo vector
, eliminando il vecchio vector
spazio e quindi aggiungendo il nuovo elemento.
std::vector
è una classe di raccolta nella libreria di modelli standard. Mettendo gli oggetti in vector
, portandoli fuori, o con lo vector
che esegue un ridimensionamento quando un elemento viene aggiunto ad un intero vector
, tutti richiedono che la classe dell'oggetto supporti un operatore di assegnazione, un costruttore di copie e la semantica del movimento. (Vedere type requirements for std::vector nonché std::vector works with classes that are not default constructible? per i dettagli.)
Un modo di pensare std::vector
è come stile C array
di elementi contigui del tipo specificato quando il vector
è definito che ha alcune funzionalità aggiuntive per integrarla nel standard Offerte di libreria di modelli. Ciò che separa uno da uno standard è che uno vector
crescerà in modo dinamico man mano che gli elementi vengono aggiunti. (Vedere std::vector and c-style arrays nonché When would you use an array rather than a vector/string? per qualche discussione su differenze.)
Utilizzando std::vector
consente l'utilizzo di altri componenti Standard Template Library, come gli algoritmi in modo da utilizzare std::vector
viene fornito con un bel paio di vantaggi rispetto a uno stile di C array
come si arriva a usa la funzionalità che esiste già.
È possibile specificare una dimensione iniziale se il massimo è noto in anticipo. (Vedere Set both elements and initial capacity of std::vector e Choice between vector::resize() and vector::reserve())
Le nozioni di base della rappresentazione fisica std::vector
sono di un insieme di puntatori che utilizzano la memoria allocata dall'heap. Questi puntatori consentono le operazioni effettive di accesso ai elementi memorizzati nel vector
, cancellazione di elementi dal vector
, iterando il vector
, determinare il numero di elementi, determinare le dimensioni, ecc
Poiché la rappresentazione fisica è memoria contigua , l'eliminazione di elementi può comportare lo spostamento di elementi rimanenti per chiudere eventuali fori creati dall'operazione di eliminazione.
Con moderno C++ spostare la semantica, il sovraccarico di std::vector
è stato ridotto in modo tale che è in genere il contenitore predefinito che sarebbe stato utilizzato per la maggior parte delle applicazioni, come raccomandato da Bjarne Stroustrup nel suo libro The C++ Programming Language 4 ° Edizione che discute C + +11.
- 1. sizeof() std :: vector (C++)
- 2. C++ in uno std :: vector
- 3. C++ std :: coppia, std :: vector e memcopy
- 4. std :: vector alternativa per C
- 5. Come funziona il costruttore di copie std :: vector?
- 6. C++ 11 std :: vector in concurrent environment
- 7. C++ 11: std :: vector :: shrink_to_fit complex
- 8. C++ std :: vector emplace vs insert
- 9. std :: vector or boost :: vector thread safe?
- 10. Copia elementi da std :: vector in std :: stack C++
- 11. std :: vector di std :: vettori contiguità
- 12. std :: vector <std::string> crash
- 13. È std :: vector :: begin() da priorC++ 11 equivalente a std :: vector :: data() in C++ 11?
- 14. Può std :: vector essere = 'd in un altro std :: vector?
- 15. Inizializzazione Eigen :: vector con std :: vector
- 16. Eigen e std :: vector
- 17. Ereditato da std :: vector
- 18. std :: vector di riferimenti
- 19. Come inizializzare std :: vector dall'array in stile C?
- 20. Come viene implementato l'inserimento di std :: vector? C++
- 21. Conversione tra C++ std :: vector e array C senza copiare
- 22. C++ 11/C++ 03 e std :: vector filo di sicurezza
- 23. std :: vector e std :: comportamento min
- 24. std :: list vs std :: vector iteration
- 25. Impossibile creare std :: vector constexpr
- 26. std :: vector più veloce di std :: unordered_set?
- 27. std :: vector :: emplace_back e std :: move
- 28. efficiente passaggio di std :: vector
- 29. preassegnati std privato :: vector in OpenMP parallelized ciclo for C++
- 30. Allocatore personalizzato in std :: vector
Basta leggere il codice nel file di intestazione ''. L'implementazione differisce da libreria a libreria. –
Philipp
Ogni volta che ridimensioni un vettore, Dio uccide un gattino. –
@Philipp: hai provato a farlo? Ci vuole un bel po 'di sforzi e dolore per passare attraverso il codice ... –