Reputation: 1758
I'm learning vectors from this post and they start off with iterators. They define .begin and .end as follows:
begin() – Returns an iterator pointing to the first element in the vector
end() – Returns an iterator pointing to the theoretical element that follows the last element in the vector
And then they give the following code snippet, I added the 3rd for loop to express my question.
#include<iostream>
#include<vector>
int main() {
std::vector <int> g1; //creating a vector
for (int i = 1; i <= 3; i++){
g1.push_back(i);
}
std::cout << "Output of beginning and end values: ";
for (auto i = g1.begin(); i != g1.end(); i++) {
std::cout << *i << " ";
}
std::cout << "\nOutput of beginning and end addresses: ";
for (auto i = g1.begin(); i != g1.end(); i++) {
std::cout << &i << " ";
}
//"Output of beginning and end values: 1 2 3"
//"Output of beginning and end addresses: 0105FB0C 0105FB0C 0105FB0C"
return 0;
}
My confusion is that the address of i
stays the same, but the value that i
has changed. Doesn't i*
mean i
is just dereferenced? So something has to be changing the value of i
if it's address is not changing so that it would be able to have a different value. I think I may be confusing iterators with pointers. I know that auto
is basically type inference but that's about it.
So my question is, how does the value of i
change, if it's address is the same for every element in the vector?
Upvotes: 2
Views: 3750
Reputation: 238401
I think I may be confusing iterators with pointers
Well, pointers are iterators, so this is understandable. But not all iterators are pointers. In other words, non-pointers can also be iterators.
I know that auto is basically type inference but that's about it.
In this case, the type is deduced to be std::vector<int>::iterator
because that is the type that std::vector<int>::begin
returns.
So my question is, how does the value of i change, if it's address is the same for every element in the vector?
The value of i
is changed by the i++
in the loop. The address where an object is stored never changes through the lifetime of the object. Regardless of whether the type of that object is pointer, some other iterator or not an iterator at all.
Upvotes: 2
Reputation: 311048
To make it more clear consider a similar code but instead of a vector there is used an array.
#include <iostream>
#include <iterator>
int main()
{
int a[] = { 1, 2, 3 };
for ( auto p = std::begin( a ); p != std::end( a ); p++ )
{
std::cout << "The address of p is " << &p
<< ", its value is " << p
<< ", and the pointed value is " << *p
<< '\n';
}
return 0;
}
The program output might look like
The address of p is 0x7ffcaf6a6830, its value is 0x7ffcaf6a683c, and the pointed value is 1
The address of p is 0x7ffcaf6a6830, its value is 0x7ffcaf6a6840, and the pointed value is 2
The address of p is 0x7ffcaf6a6830, its value is 0x7ffcaf6a6844, and the pointed value is 3
This part of the outputted strings
The address of p is 0x7ffcaf6a6830
is not being changed because it is the address of the local variable (pointer) p itself.
This part of the strings
its value is 0x7ffcaf6a683c
is being changed because within the loop the value of the pointer is changed
for ( auto p = std::begin( a ); p != std::end( a ); p++ )
^^^^
In each iteration the pointer points to the next element of the array.
This part of the strings
and the pointed value is 1
is also being changed because there is outputted the pointed value due to dereferencing the pointer.
The same things take place with the iterator of a vector.
Upvotes: 3
Reputation: 32717
&i
is the address of the local variable i
. This will not change. *i
dereferences the iterator, and returns the value at that element of the vector. &*i
will return a pointer to the element in the vector.
So you loop should use
std::cout << &*i << " ";
to see the addresses change.
Upvotes: 10