Mengapa elemen end () dalam wadah asosiatif mencetak nilai yang sama dengan elemen terakhir? [duplikat]

Dec 10 2020

Pada kode di bawah ini, nilai yang ditunjuk iterator sama untuk elemen terakhir dan kedua terakhir.

#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;
}

Dalam pemahaman saya, nilai yang ditunjukkan oleh elemen akhir harus nol. Mengapa demikian?

Jawaban

6 TonyTannous Dec 10 2020 at 20:53

Anda memanggil perilaku tidak terdefinisi, std :: set :: end

Mengembalikan iterator ke elemen setelah elemen terakhir dari set. Elemen ini bertindak sebagai placeholder; mencoba untuk mengaksesnya menghasilkan perilaku yang tidak terdefinisi.


Perilaku tidak terdefinisi membuat seluruh program menjadi tidak berarti.

1 largest_prime_is_463035818 Dec 10 2020 at 20:55

Dalam pemahaman saya, nilai yang ditunjukkan oleh elemen akhir harus nol. Mengapa demikian?

Mengapa pemahaman Anda salah, saya tidak tahu;). Kesampingkan kesusilaan: Tidak. Tidak ada "elemen akhir". The enditerator menunjuk ke salah satu masa lalu elemen terakhir. Anda tidak dapat membedakannya. Jika Anda melakukannya, Anda memunculkan perilaku yang tidak terdefinisi.

Elemen terakhir dalam penampung biasanya disebut sebagai "kembali" dan banyak penampung memiliki back()metode untuk mengaksesnya.

AsteroidsWithWings Dec 10 2020 at 21:01

Dalam pemahaman saya, nilai yang ditunjukkan oleh elemen akhir harus nol. Mengapa demikian?

Tidak.

Iterator one-past-the-end tidak "menunjuk" ke apa pun; itu tidak dapat dibedakan.

String C mungkin tampak pada awalnya sebagai pengecualian untuk aturan ini, tetapi sebenarnya tidak: string tersebut secara logis diakhiri oleh NULLkarakter yang dapat Anda periksa, tetapi itu NULLmasih merupakan bagian dari larik charobjek, dan Anda tidak dapat mendereferensi a char*itulah iterator one-past-the-end untuk array itu. Pikirkan terminator null C-string sebagai "halaman ini sengaja dikosongkan"; halaman tidak memberi Anda cerita lagi, tetapi itu masih sebuah halaman.

Mengapa elemen end () dalam wadah asosiatif mencetak nilai yang sama dengan elemen terakhir?

Itu salah satu hasil yang mungkin dari program dengan perilaku tidak terdefinisi.