vector reserve vs resize: size și capacity în C++
Află de ce reserve nu creează elemente și nu permite accesul prin indice. Compară resize, push_back, size și capacity pe un exemplu mic.
În acest material
Un vector gol rămâne gol după reserve(100). Are spațiu rezervat pentru cel puțin 100 de elemente fără o nouă realocare în acel interval de creștere, dar size() este încă zero. Accesul v[0] nu devine valid doar fiindcă există capacitate.
Două numere cu roluri diferite
size() este numărul elementelor construite în vector. capacity() este numărul pe care îl poate păstra în spațiul rezervat înainte de a avea nevoie de o realocare. Un indice pentru accesul obișnuit trebuie să fie mai mic decât size, nu doar decât capacity.
Imaginează-ți trei locuri ocupate într-un spațiu rezervat pentru zece. Poți prelucra cele trei elemente existente. Celelalte locuri nu sunt elemente suplimentare ale secvenței pe care ai voie să le indexezi ca date.
Ce operație alegi
resize(3) schimbă dimensiunea la 3. Pentru un vector de int inițial gol și alocatorul obișnuit, noile elemente sunt inițializate cu zero. După aceasta indicii 0,1,2 sunt valizi. push_back(7) adaugă un element la sfârșit și mărește dimensiunea cu unu.
reserve(100) este potrivit când intenționezi să adaugi ulterior elemente și vrei să reduci realocările. Nu este o alternativă la resize atunci când urmează să citești direct în v[i] pentru indicii 0..n-1.
Pentru citire ai două variante coerente: construiești vectorul cu n elemente și atribui pe indici, sau pornești gol, rezervi opțional spațiu și adaugi fiecare valoare prin push_back. Combinarea lui reserve cu indexarea unor elemente inexistente este greșeala.
Un vector gol are size 0 după reserve(10), apoi size 1 după push_back(7), apoi size 3 după resize(3). Numai indicii sub size sunt accesibili.Mărește schema ↗
Micșorarea dimensiunii nu promite micșorarea capacității
Dacă reduci size prin resize, elementele eliminate nu mai fac parte din vector. Capacitatea poate rămâne mai mare. Nu deduce din cantitatea de memorie rezervată că vechile elemente sunt încă accesibile ca înainte.
O realocare poate muta elementele în altă zonă și invalida pointeri, referințe sau iteratori păstrați către ele. Acest efect trebuie luat în calcul separat de simpla valoare a dimensiunii.
Test de înțelegere
Pornește gol, aplică reserve(10), apoi push_back(7), apoi resize(3). Dimensiunile sunt 0,1,3. Nu presupune o valoare exactă a capacității dincolo de garanțiile operațiilor. Pentru definițiile formale vezi capacitatea vectorului în specificația C++.
Continuă cu vectori clasici, vector și iteratori și inserare și ștergere.
Întrebări frecvente
Care este diferența dintre reserve și resize la vector?
reserve pregătește capacitate fără să mărească numărul elementelor. resize schimbă dimensiunea logică și construiește sau elimină elemente. Indicii valizi sunt determinați de size(), nu de capacity().
Pot scrie în v[0] după reserve(100) pe un vector gol?
Nu. Vectorul are încă zero elemente. Folosește push_back pentru a adăuga un element sau resize pentru a crea numărul necesar de elemente înainte de acces.
De ce capacity poate fi mai mare decât size?
Vectorul poate rezerva spațiu suplimentar pentru creșteri ulterioare, evitând o realocare la fiecare adăugare. Spațiul rezervat nu reprezintă elemente pe care le poți accesa prin indici.