Reputation: 7994
Let's say I have a std::vector and I get by some means the address of the n-th element. Is there a simple way (faster than iterating through the vector) to get the index at which the element appears, given the base address of my std::vector? Let's assume I'm sure the element is in the vector.
Upvotes: 12
Views: 8875
Reputation: 253
On the way of learning, I have taken the following notes:
#include <iostream>
#include <vector>
int main() {
std::vector<std::string> words={"This","is","just","a","trial!"};
size_t i; //using the contiguous property of a vector:
for (auto const& elem : words) {
i = &elem - &*words.begin();// or
i = &elem - &words.front();// or
i = &elem - words.data();// or
i = std::addressof(elem) - std::addressof(words[0]);
if(std::addressof(elem) == &words.front())
std::cout << elem <<" (at"<<&elem<<") relative to ("<< &words[0] << ") takes position @#"<<i<< std::endl;
else std::cout << elem <<" (at"<<&elem<< ") takes position @#"<<i<< std::endl;
}
return 0;
}
Test run here. It is open to further study (or learn from masters) which one is the most secured/safe and/or most efficient approach.
Upvotes: 0
Reputation: 1356
distance( xxx.begin(), theIterator);
The above will only work for a vector::iterator. If you only have a raw pointer to an element, you must use it this way:
distance(&v[0], theElementPtr);
Upvotes: 5
Reputation: 81349
Since you know the element is within the vector, and vector guarantees that its storage is contiguous, you could do:
index = element_pointer - vector.data();
or
index = element_pointer - &vector[0];
Note that technically the contiguous guarantee was introduced in C++03, but I haven't heard of a C++98 implementation that doesn't happen to follow it.
Upvotes: 20
Reputation: 23848
Yes - because a vector guarantees all elements are in a contiguous block of memory you can use pointer arithmetic to find it like so
#include <iostream>
#include <vector>
int main(int argc, char *argv[])
{
std::vector<int> vec;
for(int i=0; i<10; ++i)
{
vec.push_back(i);
}
int *ptr=&vec[5];
int *front=&vec[0];
std::cout << "Your index=" << ptr-front << std::endl;
return 0;
}
Upvotes: 1