Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About iterator of containers

I do not know, why does it output 1024?

vector<int> default_container = { 1,2,3,4,5,6,7,78,8,1024 };
cout << *default_container.end() << endl; // 0
default_container.pop_back();

for (auto it : default_container) 
{
    cout << it << ",";
}
cout << endl;

cout << *default_container.end() << endl;   // 1024 why?why?why?why?
cout << *--default_container.end() << endl; // 8

like image 733
littleZ Avatar asked Dec 09 '22 23:12

littleZ


1 Answers

Your program has Undefined behavior!

You are de-referencing the end iterator, at the lines

cout << *default_container.end() << endl;
...
cout << *default_container.end() << endl;

which gives you undefined behavior. Form cppreference.com the std::vector::end, std::vector::cend

enter image description here

Returns an iterator to the element following the last element of the vector. This element acts as a placeholder; attempting to access it results in undefined behavior.

Means, anything can be happened; therefore you shouldn't be relaying on its result and should not be doing it!


That being said, it looks like that you want to access the last element in the vector. If that the case, for a non-empty vector you have multiple other (safe) choices:

  1. Using std::vector::back

    // prints first 8 from last; due to "default_container.pop_back()"  
    std::cout << default_container.back(); 
    
  2. Using std::prev

    #include <iterator>
    
    // prints first 8 from last; due to "default_container.pop_back()"  
    std::cout << *std::prev(default_container.end()); 
    
  3. Using reverse iterator std::rbegin

    // prints first 8 from last; due to "default_container.pop_back()"  
    std::cout << *std::rbegin(default_container);
    

As a side note, see: Why is "using namespace std;" considered bad practice?

like image 183
JeJo Avatar answered Dec 12 '22 13:12

JeJo