3

Fairly new to C++. Referring to this snippet of code:

for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';

In particular when initializing the iterator and the end condition. Does each element in the vector have a unique memory address to point to? Or do iterators work differently than pointers?

MKSnazzy
  • 71
  • 1
  • 1
  • 10

4 Answers4

6

Although iterators are not necessarily pointers (although for std::vectors most non-debug implementations implement them as thin wrappers around pointers), std::vector is guaranteed to have its elements contiguous in memory. Which implies that YES, every element has a distinct memory location.

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • @ChristopherOicles Haha, many agree that `std::vector` should not be called a container. – vsoftco Oct 01 '16 at 01:27
  • Yeah, in my opinion, it should not be the nutty exception that it is, rather if you want an optimized bit vector, use `std::bitset` – Christopher Oicles Oct 01 '16 at 01:29
  • @ChristopherOicles I was reading somewhere that many standard committee members believe the `std::vector` specialization to be a mistake. I totally agree that `std::bitset` is way better. – vsoftco Oct 01 '16 at 01:31
2

Each element does indeed have a unique address in memory. Basically, let's look at this sample vector:

template <class T>
class vec
{
public:
 vec() ;
 ~vec() ;
 T * elements;
} 

You can see here is just an example of a vector. So what the iterators do is point to each pointer in the element. They may not have a unique address themselves, but they point to each element in the vector. So each iterator has UNIQUE memory addresses.

And like I said in my comments, they can't work differently since the Vectors and their iterators are libraries made by people like you, using C++. They can't work differently from pointers which are built in the C++ language.

Also from references: (draft of C++0x):

23.2.6 Class template vector [vector]

1 A vector is a sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

zondo
  • 19,901
  • 8
  • 44
  • 83
amanuel2
  • 4,508
  • 4
  • 36
  • 67
  • As I'm pretty new to C++, I don't know what most of that code means. Are you saying each iterator has a unique address? Or each vector element has a unique address? – MKSnazzy Oct 01 '16 at 01:07
  • @Matt what I am saying is that each vector element has a new address. And each iterator points to the vector element's address. – amanuel2 Oct 01 '16 at 01:08
  • @Matt I'm assuming your talking about template specialization. That's just a way of creating a type that will be defined when an object is initiated. Just treat T it as a type like int. – amanuel2 Oct 01 '16 at 01:10
  • @Matt glad to help :) – amanuel2 Oct 01 '16 at 01:11
2

Every object (that exists at a particular time) has a unique address. The elements of a vector are objects (with the exception of the abomination which is the std::vector<bool> specialization). So yes, they all have unique addresses. Keep in mind though, that when you add elements to a vector, it may reallocate. And when it reallocates, all the old objects are destroyed and moved to new objects with different addresses, and the old memory is free to be reused, perhaps by further reallocations of the same vector. The following is possible, for example:

std::vector<int> v;
v.push_back(0);
std::intptr_t a0 = (std::intptr_t)&v[0];

v.push_back(1); // a reallocation may happen here
v.push_back(2); // and perhaps another one here

std::intptr_t a2 = (std::intptr_t)&v[2];

if (a0 == a2) {
    std::cout << "This code is unlikely to be executed, but technically possible.";
}
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • *"with the exception of the **abomination** which is the `std::vector`"* - Haha... I had to pause there and throw an upvote before I continued reading the rest of your answer – WhiZTiM Oct 01 '16 at 01:33
1

From [vector.overview]/1

A vector is a sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

Emphasis mine

So since &v[n] is valid for for all n in [0, size()) then ever element in the vector has its own unique address.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Hi, I'm newer to C++ so some of that is confusing. Thanks for confirming for me that each element has its own memory address. – MKSnazzy Oct 01 '16 at 01:07
  • 1
    He’s citing the language standard. It does say that you can take `&v[i]` for any `i` in range and get a unique address, which you can dereference with `*`. – Davislor Oct 01 '16 at 01:15