Por que o elemento end () no container Associativo imprime o mesmo valor do último elemento? [duplicado]

Dec 10 2020

No código abaixo, o valor para o qual o iterador aponta é o mesmo para o último e o penúltimo elemento.

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

No meu entendimento, o valor apontado pelo elemento final deve ser nulo. Porque isto é assim?

Respostas

6 TonyTannous Dec 10 2020 at 20:53

Você invocou um comportamento indefinido, std :: set :: end

Retorna um iterador para o elemento após o último elemento do conjunto. Este elemento atua como um espaço reservado; tentar acessá-lo resulta em um comportamento indefinido.


O comportamento indefinido torna todo o programa sem sentido.

1 largest_prime_is_463035818 Dec 10 2020 at 20:55

No meu entendimento, o valor apontado pelo elemento final deve ser nulo. Porque isto é assim?

Por que seu entendimento está errado, eu não posso dizer;). Sinceridade à parte: Não. Não existe um "elemento final". O enditerador aponta para um após o último elemento. Você não pode desreferenciá-lo. Se você fizer isso, você invoca um comportamento indefinido.

O último elemento em um contêiner é normalmente referido como "back" e muitos contêineres têm um back()método para acessá-lo.

AsteroidsWithWings Dec 10 2020 at 21:01

No meu entendimento, o valor apontado pelo elemento final deve ser nulo. Porque isto é assim?

Não é.

O iterador que passou do fim não "aponta" para nada; não é desreferenciável.

Strings C podem parecer à primeira vista uma exceção a esta regra, mas não são: elas são terminadas logicamente por um NULLcaractere que você pode verificar, mas que NULLainda faz parte de uma matriz de charobjetos, e você não pode desreferenciar um char*esse é o iterador que ultrapassa o fim dessa matriz. Pense no terminador nulo de uma string C como uma "página deliberadamente deixada em branco"; a página não conta mais nenhuma história, mas ainda é uma página.

Por que o elemento end () no container Associativo imprime o mesmo valor do último elemento?

Esse é um resultado possível de um programa com comportamento indefinido.