Różnica między rozmiarem vectora a jego pojemnością

0

Jaka jest różnica między rozmiarem vectora (kontener z STL'a rzecz jasna), a jego pojemnością ?

Dla przykładu mam taki kod:

#include <iostream> 
#include <vector> 

int main() 
{
  std::vector<int> moj_wektor(100);  // WEKTOR KTÓRY MA 100 elementów 
  std::cout << "Pojemnosc wektora:  " << myvector.capacity() << '\n'; // RZECZ JASNA BEDZIE 100
 
  myvector.resize(10); // ZMNIEJSZAM ROZMIAR DO 10

  std::cout << "Pojemnosc wektora:  " << myvector.capacity() << '\n'; // POJEMNOŚĆ WEKTORA SIE NIE ZMNIEJSZYLA 
 
return 0; 
}

 

Po co w ogóle jest ta metoda resize() ? Ma ustawiac rozmiar vectora, tymczasem tego nie robi. Z tego wniosek że istnieje różnica między rozmiarem vectora i jego pojemnością...

Powiedzmy zatem że mamy vector o rozmiarze 100 elementów zdefiniowany tak:

vector<int> myVec(100); 
 

wiemy że jego rozmiar to 100. Zmniejszamy jego rozmiar do 10 za pomocą metody resize();

vector<int> myVec.resize(10); 
 

Teraz ma tylko 10 elementów.

Odpalamy jakąś pętle w której dodajemy do niego więcej niż 10 elementów.

for(int i=0; i<55; i++) 
   myVec.push_back(i); 
 

**
I kod się kompiluje, chociaż dodaliśmy więcej elementów niż wynosi jego rozmiar ?** 55, a on sam ma rozmiar 10.

Dodatkowo jak to sobie wydrukujemy, tj. zawartość vectora:

for(std::vector<int>::const_iterator it = myVec.begin(); it != myVec.end(); it++)
   std::cout << *it << ' ';
 

To dostajemy w wyniku tego 10 zer i liczby od 0 do 54, tak jakby zostały zarezerwowane te pierwsze elementy, tj. 10 zer a następnie dodane 55 liczb z tej pętli.

**Pytanie kolejne: Dlaczego te liczby z pętli nie nadpisały tych zer które pewnie powstały w wyniku działania funkcji resize() ? **

3

Rozmiar vectora to liczba przechowywanych w nim elementów.
Pojemność vectora to liczba elementów jakie mogą być przechowane w aktualnie zaalokowanej przez niego pamięci.

Dlaczego te liczby z pętli nie nadpisały tych zer które pewnie powstały w wyniku działania funkcji resize() ?

Resize 'dodaje' do vectora tyle elementów ile potrzeba (utworzonych przy pomocy konstruktora domyślnego)
do tego dodajesz potem swoje liczby.

0

Musisz spędzić tutaj więcej czasu: http://www.cplusplus.com/reference/vector/vector/resize/

1

A tuż obok jest funkcja która może optymalizować capacity: http://www.cplusplus.com/reference/vector/vector/shrink_to_fit/

0

Czyli resize() ni mniej ni więcej daje 3 rezultaty:

  1. Jeśli argument resize() jest większy od ilości aktualnie przechowywanym elementów (size()) to nic się nie dzieje i te nowe miejsca są wypełniane jakimiś wartościami przez konstruktor domyślny.

  2. Jesli argument resize() jest mniejszy od ilości aktualnie przechowywanych elementów (size()) to ucina po prostu od końca te elementy.

  3. Jeśli argument resize() jest taki sam jak wartość zwracana przez size() to nic się nie dzieje.

0
ond3 napisał(a):
  1. Jeśli argument resize() jest większy od ilości aktualnie przechowywanym elementów (size()) to nic się nie dzieje i te nowe miejsca są wypełniane jakimiś wartościami przez konstruktor domyślny.

Jeśli nowy rozmiar jest większy niż capacity() to następuje ponowna alokacja i kopiowanie (przeniesienie) elementów.
Można również podać wartość, którą dostają nowe elementy.

ond3 napisał(a):

Teraz ma tylko 10 elementów.
Odpalamy jakąś pętle w której dodajemy do niego więcej niż 10 elementów.

for(int i=0; i<55; i++) 
   myVec.push_back(i); 

I kod się kompiluje, chociaż dodaliśmy więcej elementów niż wynosi jego rozmiar ? 55, a on sam ma rozmiar 10.

push_back() zwiększa rozmiar wektora (i powoduje ponowną alokację jeśli trzeba), więc to jaki rozmiar wektor ma w danej chwili nie ma żadnego znaczenia

0
Tutaj był zlot klopsów, klops na klopsie, istne klopsonarium

Najważniejsze, żeby nie pomylić resize z reserve! :D patrz post @twonek.

Odpal sobie coś takiego

vector< unsigned > vec;
unsigned i = 0;
do {
 vec.push_back( i );
printf( "Size: %u\tCapacity:%u\n", vec.size(), vec.capacity() );
} while( i < 5000 );
0

kolejna, głupia i bezsensowna dyskusja na temat czegoś, czego nikt nie używa,

chcesz miec fixed size? użyj std::array, a nie jakieś zabawy z capacity i resize, a jeżeli już używasz vectora, to pozwól stlowi zająć się realokacją Twoich obiektów dla size() > capacity()

ciekawe, który z Was użył kiedykolwiek std::vector<T>::capacity() w kodzie produkcyjnym

edit:

a jak coś jest ciekawe to -> http://en.cppreference.com/w/cpp/container/vector tutaj jest wiedza

1
tajny_agent napisał(a):
 std::vector< Ksiazka > polka( 20 ); // półka na książki, zmieści 20 książek; size() = 0, capacity() = 20
...
polka.resize( 10 ); // pragniesz, aby Twoja półka zmieściła 10 książek. Aktualnie pomieści ich 20, więc nie ma sensu obcinać półki.
polka.resize( 50 ); // poszerasz półkę. zajmuje teraz pół ściany w pokoju, ale pomieści 50 książek
( ...układasz na półce 35 książek... ) // size() = 35, capacity() = 50
polka.shrink_to_fit(); // obcinasz półkę tak, aby pomieściła tylko 35 książek i nie marnowała miejsca na ścianie, size() = 35, capacity() = 35

Niestety jest tutaj więcej nieprawdy niż prawdy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1