SRR
SRR

Reputation: 1758

Understanding .begin and .end in vectors

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

Answers (3)

eerorika
eerorika

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

Vlad from Moscow
Vlad from Moscow

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

1201ProgramAlarm
1201ProgramAlarm

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

Related Questions