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

2015-02-01 16:59
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() ?

edytowany 1x, ostatnio: ond3, 2015-02-01 17:00

Pozostało 580 znaków

2015-02-01 17:06
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.

edytowany 3x, ostatnio: Sopelek, 2015-02-01 17:19

Pozostało 580 znaków

2015-02-01 17:07
0

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

Pozostało 580 znaków

2015-02-01 17:13
1

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


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2015-02-01 17:18
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.

Pozostało 580 znaków

2015-02-01 17:37
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
edytowany 2x, ostatnio: twonek, 2015-02-01 17:45

Pozostało 580 znaków

2015-02-01 22:23
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 );

Wole wizerunek z nożem w zębach, przejść po trupie
Niż zgrywać ćwierćinteligenta z piórkiem w d.
edytowany 2x, ostatnio: tajny_agent, 2015-02-02 16:51

Pozostało 580 znaków

2015-02-01 22:34
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

edytowany 1x, ostatnio: gośćabc, 2015-02-01 22:35
Co jest złego w tym, że ktoś chce wiedzieć czym co się różni zamiast używać "na pałę". Dział newbie chyba do tego służy, prawda? - tajny_agent 2015-02-02 00:25
w moim poście nie ma nic o używaniu czegokolwiek "na pałę", to jest taka metafora do tego, że wg mnie pomagający powinni bardziej nakierowywać początkujących na dobry tor, a nie prowadzić dyskusję ("na 10 postów") na taki temat - gośćabc 2015-02-02 00:38

Pozostało 580 znaków

2015-02-01 22:39
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.

Pokaż pozostałe 2 komentarze
Przecież napisałem, że jest to uproszczone i ma na celu pokazanie logicznej różnicy między size i capacity a nie konkretnej implementacji vectora. Z resztą to co proponujesz w komentarzu powyżej sam umieściłem wcześniej w swoim poście. - tajny_agent 2015-02-02 00:22
Uproszczone nie może być niezgodne z każdą implementacją vectora zgodną ze standardem. Już pierwszy komentarz wprowadza w błąd, bo taka deklaracja vectora daje size()==20, a mówiąc Twoim przykładem na półce już jest 20 książek. - twonek 2015-02-02 00:26
A widzisz, bo tam miało być reserve :P - tajny_agent 2015-02-02 00:34
To tylko pierwszy problem. Dalej jest tak samo, po resize(50) size()==50, jako również po shrink_to_fit(). - twonek 2015-02-02 00:43
O_o wyszło na jaw moje obycie z wektorem. Rzeczywiście naplotłem bzdur na potęgę. Dzięki za zwrócenie uwagi :) - tajny_agent 2015-02-02 16:47

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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