Dlaczego vector::reserve nie wypełnia całej zarezerwowanej przestrzeni obiektami?

0

Witam

Bawię się z klasą vector. Konkrentie z implementacją dostarczoną z VS 2012 (gdyby to miało znaczenie w tym kontekście).
Dajmy na to że mam klasę Dane i klasę

std::vector<Dane> v;
//i dalej
Dane d1;
v.push_back(d1);//zawola konstruktor kopiujący
v.reserve(3);//raz zawoła konstruktor kopiujący jako iż musi przenieść d1;
v.resize(3);//dopiero to woła konstruktory. Jeden kopiujący (d1) i dwa zwykłe (do dopełnienia wektora)

Więc moje pytanie brzmi: jak to wygląda od środka. A konkreniej: jakie operacje są wykonywane gdy wołamy reserve() i jaka jest wewnętrzna reprezentacja struktury pamięciowej stojąca za vector'em. Zwykła tablica z wartownikiem indeksu raczej nie, bo tablice obiektów wypełniane są obiektami w momencie utworzenia tablicy.

I drugie pytanie. W kontekście struktury pamięciowej stojącej za vector'em. Gdzie jest błąd w moim rozumowaniu:
-operator [] nie sprawdza zakresu (szybki ale na tyle bezpieczny na ile programista uwazny/dobry)
-reserve(n) rezerwuje (przydziela?) pamięć dla n elementów
To dlaczego taki kod się wykrzacza?

Vector<Dane> v;
v.reserve(10);
v[5];//wyjątek

Pozdrawiam

2

Vector::reserve alokuje tylko pamięć ale pozostawia ją niezainicjalizowaną, w przeciwieństwie do Vector::resize. Dlatego program wywala Ci wyjątek, bo operujesz na niezainicjalizowanej pamięci. Nie ma tam obiektów tylko zarezerwowana odpowiednia ilość pamięci na nie. A sama klasa Vector to reprezentacja tablicy.

Tutaj masz więcej:
http://www.cplusplus.com/reference/vector/vector/
http://www.cplusplus.com/reference/vector/vector/reserve/
http://www.cplusplus.com/reference/vector/vector/resize/

0

Sensowna odpowiedź na to pytanie:
http://stackoverflow.com/a/2096974

http://www.cplusplus.com/reference/memory/allocator/allocate/

The storage is aligned appropriately for objects of type value_type, but they are not constructed.

0

Możesz sobie sam zaalokować:

std::vector<int> v;
v.reserve(5);
new (&v[2]) int(17);

http://ideone.com/4Sfe12

1

Użycie reserve(n) gwarantuje brak realokacji (i inwalidacji iteratorów) po użyciu push_back()/emplace_back() tak długo, jak size() ≤ capacity(), gdzie capacity() ≥ n.

Od strony implementacyjnej, reserve odpowiada za alokację pamięci, później dopełnianej placement new, np. za pomocą resize lub push_back.

Przy okazji, w Twoim przypadku resize() nie powinno wołać konstruktora kopiującego dla pierwszego elementu: http://melpon.org/wandbox/permlink/ZtZGjAyKzlI4HYMg

0

Generalnie wiem, że

reserve()

tylko alokuje pamięć a resize()

 ją wypełnia obiektami. 

Przeczyłałem w dokumentacji oraz sprawdziłem osobiście logując na konsole wołanie konstruktorów jak w pytaniu.

Bardziej mnie interesuje jak zaalokować pamięć bez tworzenia obieków. Wszak 

```cpp
value_type * mem = (value_type*)new value_type[5];

woła konstruktory. Poczytałem troche i odkryłem, że malloc tylko alokuje pamięć:

value_type * mem =(value_type*) alloc(5*sizeof(value_type));

Ale to są tylko moje spekulacje/domysły. Może ktoś się wypowiedzieć czy rzeczywisćie tak to się odbywa? A może jeszcze jakoś inaczej?

Natomiast wycofuję pytanie o wysyp programu przy dostępie do elementów o index'ie tylko zarezerwowanym. To jednak nie był wysyp tylko debug asercje.

1

Zobacz sobie jak mozna sie bawic alokowaniem pamieci i wywolywaniem konstruktorow - mniej wiecej to co robi vector:
http://ideone.com/Mi9d0V

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