2012-12-15 9 views
5

Czytałem kilka dokumentów na temat STL i tam napisano, że funkcja end() zwraca iterator bajtu obok ostatniego elementu kontenera.Iteratory STL: container.end()

Zastanawiam się, co się stanie, jeśli kontener zajmie ostatnie bajty całej dostępnej pamięci. Co się wtedy stanie?

+0

Wskaźnik jest rodzajem iteratora, a nie odwrotnie. –

+0

@BenjaminLindley, czy możesz mi powiedzieć, dlaczego tak jest? Jestem początkującym ... – Kolyunya

+0

Po prostu jestem wybredna. To, do czego dążyłem, to to, że istnieje wiele rodzajów iteratorów, a nie tylko wskaźników. Tak więc nie jest tak, że "iteratory są wskaźnikami". * Niektóre * iteratory są wskaźnikami, a niektóre nie. Teraz rozmowa, "wskaźniki są iteratorami", to prawda, a przynajmniej tak zamierzałem sugerować. Jednak to nie jest prawda. Niektóre wskaźniki nie są iteratorami, niektóre są po prostu używane jako odniesienie. Więc się pomyliłem. –

Odpowiedz

4

Model pamięci C++ gwarantuje, że zawsze można utworzyć wskaźnik do elementu po ostatnim elemencie tablicy. Jeśli go nie ma, system nie zezwoli na przydzielenie obiektu w tej lokalizacji lub zawinie go. Należy również zauważyć, że jest to potencjalny problem dla tablic, ponieważ inne pojemniki mogą używać typów iteratorów, które zajmują się przeszłością pozycji końcowej w innej odpowiedniej formie: w pełni kontrolują działanie operacji przyrostowej.

+0

oznacza to, że nie pozwolę sobie na stworzenie tablicy, która zajmuje całą dostępną w chwili obecnej pamięć, prawda? Co najmniej jeden bajt musi pozostać? Czy rozumiem? – Kolyunya

+0

@Kolyunya: Konstrukcja C++ nie wyklucza tego, ale większość systemów operacyjnych nadal na to nie pozwala. –

+1

@Kolyunya: Powiedzmy, że pracowałeś nad 16-bitowym systemem wbudowanym i utworzyłeś tablicę, która miała 16-bitową liczbę całkowitą na pozycji 0xFFFE. Dodaj jedną liczbę całkowitą (2 bajty) i zawija się, aby uzyskać wartość 0x0000. Jeśli wykonasz proste porównanie iteratorów, będą one zarówno 0, jak i i == end(). Wszystko dobrze. –

3

Koniec iteratora (przynajmniej w przenośni) wskazuje na koniec kontenera tylko za. Prawidłowe elementy w kontenerze przechodzą od *container.begin() do *container.end()-1.

Innymi słowy, możesz porównać inny iterator z iteratorem końcowym, aby sprawdzić, czy są równe (co wskazuje, że osiągnąłeś koniec pozycji w pojemniku), ale możesz nie dereferencja, która kończy iterator (tzn. nie możesz próbować uzyskać dostępu do pozycji, do której się odnosi).

Edycja: Przepraszamy, rodzaj błędnie zadającego pytanie: cóż, jeśli pojemnik faktycznie wykorzystał ostatni bajt pamięci (rzadko/mało prawdopodobny, ale teoretycznie możliwy), typowo zobaczysz zawijanie adresu do początku pamięci, zakładając, że był to iterator, który naprawdę działał pod względem adresu, oczywiście. W takim przypadku zazwyczaj zmienia się to w adres 0, który nadal można odróżnić od dowolnego poprawnego adresu (tj. 0 zostanie przekonwertowany na wskaźnik zerowy, który nie może być prawidłowym wskaźnikiem).

W typowym przypadku jednak jest prawdopodobne, że coś takiego nie byłoby dozwolone. Na przykład w większości 32-bitowych systemów użytkownik jest ograniczony do korzystania z pierwszych 2 lub 3 gigabajtów przestrzeni adresowej, a górne adresy są zarezerwowane dla systemu operacyjnego.

+0

Pytanie dotyczy pytania, co się stanie, jeśli nie ma już adresów pamięci. Iterator wskazuje na pamięć, która fizycznie nie istnieje. – Mosby

+0

Co jeśli ostatni element wskazuje na ostatni bajt w pamięci. Co wtedy wskaże metoda .end() (przynajmniej w przenośni)? – Borgleader

+0

@Borgleader: nic, ale to nie ma znaczenia. – rici

Powiązane problemy