Natknąłem się na następujące stwierdzenia:
resize(n)
- Zmienia rozmiar kontenera, aby zawierał elementy „n”.
shrink_to_fit()
- Zmniejsza pojemność pojemnika w celu dopasowania do jego rozmiaru i niszczy wszystkie elementy poza pojemnością.
Czy istnieje jakaś znacząca różnica między tymi funkcjami? wchodzą w wektory w c ++
shrink_to_fit
zmienia pojemność.capacity
isize
?Odpowiedzi:
Wektory mają dwa atrybuty „długości”, które oznaczają różne rzeczy:
size
to liczba użytecznych elementów w wektorze. Jest to liczba przechowywanych rzeczy. Jest to długość koncepcyjna.capacity
to ile elementów zmieściłoby się w ilości pamięci, którą wektor aktualnie przydzielił.capacity >= size
musi zawsze być prawdą, ale nie ma powodu, aby zawsze byli równi. Na przykład, po usunięciu elementu, zmniejszenie alokacji wymagałoby utworzenia nowego alokacji o jeden segment mniejszego i przeniesienia pozostałej zawartości („alokuj, przenieś, za darmo”).Podobnie, jeśli
capacity == size
dodasz element, wektor może zwiększyć alokację o jeden element (kolejna operacja „alokuj, przenieś, swobodnie”), ale zwykle dodajesz więcej niż jeden element. Jeśli pojemność musi wzrosnąć, wektor zwiększy swoją pojemność o więcej niż jeden element, dzięki czemu można dodać jeszcze kilka elementów przed ponownym przeniesieniem wszystkiego.Dzięki tej wiedzy możemy odpowiedzieć na twoje pytanie:
std::vector<T>::resize()
zmienia rozmiar tablicy. Jeśli zmienisz rozmiar na mniejszy niż jego obecny rozmiar, nadmiar obiektów zostanie zniszczony. Jeśli zmienisz jego rozmiar na większy niż jego obecny rozmiar, „nowe” obiekty dodane na końcu zostaną domyślnie zainicjowane.std::vector<T>::shrink_to_fit()
prosi o zmianę pojemności w celu dopasowania do bieżącego rozmiaru. (Implementacje mogą, ale nie muszą uwzględniać tego żądania. Mogą zmniejszyć pojemność, ale nie zrównają się z wielkością. Mogą w ogóle nic nie robić.) Jeśli żądanie zostanie spełnione, spowoduje to odrzucenie części lub całości niewykorzystanej części przydział wektora. Zwykle używasz tego, gdy skończysz budować wektor i nigdy nie dodasz do niego innego elementu. (Jeśli wiesz z góry, ile elementów dodasz, lepiej byłobystd::vector<T>::reserve()
powiedzieć wektorowi przed dodaniem jakichkolwiek elementów zamiast polegać nashrink_to_fit
robieniu czegokolwiek.)Więc używasz,
resize()
aby zmienić, ile rzeczy jest koncepcyjnie w wektorze.Używasz tego,
shrink_to_fit()
aby zminimalizować nadmiar miejsca, które wektor wewnętrznie przydzielił, bez zmiany ilości elementów koncepcyjnie w wektorze.źródło
shrink_to_fit
to nie wszystko albo nic. Implementacja może częściowo zmniejszyć wydajność. Rozważmy na przykład implementację, która ogranicza pojemność wektora do potęg dwóch.To jest błędna charakterystyka tego, co się dzieje. Sekretnie, zniszczenie wszystkich elementów poza częścią pojemności nie jest dokładne.
W C ++, gdy pamięć dynamiczna jest używana dla obiektów, istnieją dwa kroki:
Gdy obiekty w dynamicznie przydzielanej pamięci są usuwane, istnieją również dwa kroki, które odzwierciedlają kroki budowy, ale w odwrotnej kolejności:
Pamięć przydzielona poza rozmiar kontenera to tylko bufor. Nie przechowują żadnych poprawnie zainicjowanych obiektów. To tylko surowa pamięć.
shrink_to_fit()
upewnia się, że nie ma dodatkowej pamięci, ale w tych lokalizacjach nie było żadnych obiektów. Dlatego nic nie jest niszczone, tylko pamięć jest zwalniana.źródło
Zgodnie ze standardem C ++ w stosunku do
shrink_to_fit
i w stosunku do
resize
Oczywiste jest, że funkcje pełnią różne funkcje. Ponadto pierwsza funkcja nie ma parametru, a druga funkcja ma nawet dwa parametry. Ta funkcja
shrink_to_fit
nie zmienia wielkości kontenera, ale może ponownie przydzielić pamięć.źródło