#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> A;
A.push_back(1);
A.push_back(2);
A.push_back(3);
auto it = A.begin();
cout << *it << ' ';
advance(it, 1);
cout << *it << ' ';
advance(it, 1);
cout << *it << ' ';
advance(it, 1);
cout << *it << ' ';
advance(it, 1);
cout << *it << ' ';
}
I belive that list
is a double linked list.
Surprisingly, the output is 1 2 3 3 1
.
Can someone explain what's happening here?
Here are questions:
- When we advance twice, we are at the node with
3
. Here, an additionaladvance
moves the iterator toA.end()
. I believe thatA.end()
is an imaginary node that does not point to the original element. However, it prints out3
. Why? - How come it prints out
1
at the end? Thelist
is not a circular queue.
CodePudding user response:
Dereferencing the end iterator is undefined. The end iterator points one past the last element in the list. It does not not refer to an element in the list, because there is no element past the last.
Advancing the end iterator further is undefined as well.
Your program has undefined behavior.
Undefined behavior means anything can happen. The runtime behavior of code without undefined behavior is specified in the langauge standard (some is implementation defined or unspecified, but lets keep it simple). On the other hand, when your code has undefined behavior then you get no guarantee what the resulting program runtime behavior will be. Your output could be "Hello World"
.
Of course the output is not "Hello World"
and there is a reason why you see the output you do see. Though, these reasons are not related to how C works. To understand why you get the output you get you would have to study the assembly generated by the compiler. Eventually to understand why the compiler did generate this assembly you would need to study implementation details of your compiler. However, if you want to learn about C then any of this is futile and all you need to know is that your code has undefined behavior.