Dlaczego element end () w kontenerze asocjacyjnym drukuje tę samą wartość co ostatni element? [duplikować]

Dec 10 2020

W poniższym kodzie wartość wskazywana przez iterator jest taka sama dla ostatniego i przedostatniego elementu.

#include <iostream>
#include <set>
using namespace std;


int main() 
{
    set<int> s1 = {4,3,2,5,1};
    set<int>::iterator i;
    
    i = s1.end();
    cout << *i << endl; // 5
    
    i--;
    cout << *i << endl; // 5
    
    
    cout << *s1.end() << endl;  // 5
    cout << *(--s1.end()) << endl;  // 5
    
    return 0;
}

W moim rozumieniu wartość wskazywana przez element końcowy powinna być zerowa. Dlaczego tak jest?

Odpowiedzi

6 TonyTannous Dec 10 2020 at 20:53

Wywołałeś niezdefiniowane zachowanie, std :: set :: end

Zwraca iterator do elementu następującego po ostatnim elemencie zestawu. Ten element pełni rolę symbolu zastępczego; próba uzyskania do niego dostępu skutkuje niezdefiniowanym zachowaniem.


Niezdefiniowane zachowanie sprawia, że ​​cały program jest bez znaczenia.

1 largest_prime_is_463035818 Dec 10 2020 at 20:55

W moim rozumieniu wartość wskazywana przez element końcowy powinna być zerowa. Dlaczego tak jest?

Dlaczego rozumiesz źle, nie potrafię powiedzieć;). Pomijając złośliwość: Nie. Nie ma „elementu końcowego”. Te endpunkty iteracyjnej do jednego za ostatnim elementem. Nie możesz tego usunąć. Jeśli to zrobisz, wywołasz niezdefiniowane zachowanie.

Ostatni element w kontenerze jest zwykle określany jako „tył”, a wiele kontenerów ma back()metodę dostępu do niego.

AsteroidsWithWings Dec 10 2020 at 21:01

W moim rozumieniu wartość wskazywana przez element końcowy powinna być zerowa. Dlaczego tak jest?

Tak nie jest.

Iterator jeden po drugim nie „wskazuje” na nic; nie można jej usunąć.

C-stringi mogą początkowo wydawać się wyjątkiem od tej reguły, ale tak nie jest: są logicznie zakończone NULLznakiem, który możesz sprawdzić, ale NULLnadal jest częścią tablicy charobiektów i nie możesz wyłuskać char*to jest iterator jeden po drugim dla tej tablicy. Wyobraź sobie zerowy terminator łańcucha C jako „ta strona celowo pozostawiona pusta”; strona nie zawiera już żadnej historii, ale nadal jest stroną.

Dlaczego element end () w kontenerze asocjacyjnym drukuje tę samą wartość co ostatni element?

To jeden z możliwych wyników działania programu z niezdefiniowanym zachowaniem.