[c++] Convert iterator to pointer?

I have a std::vector with n elements. Now I need to pass a pointer to a vector that has the last n-1 elements to a function.

For example, my vector<int> foo contains (5,2,6,87,251). A function takes vector<int>* and I want to pass it a pointer to (2,6,87,251).

Can I just (safely) take the iterator ++foo.begin(), convert it to a pointer and pass that to the function? Or use &foo[1]?

UPDATE: People suggest that I change my function to take an iterator rather than a pointer. That seems not possible in my situation, since the function I mentioned is the find function of unordered_set<std::vector*>. So in that case, is copying the n-1 elements from foo into a new vector and calling find with a pointer to that the only option? Very inefficient! It's like Shlemiel the painter, especially since i have to query many subsets: the last n-1, then n-2, etc. elements and see if they are in the unordered_set.

This question is related to c++ stl pointers vector iterator

The answer is


A safe version to convert an iterator to a pointer (exactly what that means regardless of the implications) and by safe I mean no worries about having to dereference the iterator and cause possible exceptions / errors due to end() / other situations

#include <iostream>
#include <vector>
#include <string.h>

int main()
{
    std::vector<int> vec;

    char itPtr[25];
    long long itPtrDec;
    
    std::vector<int>::iterator it = vec.begin();
    memset(&itPtr, 0, 25);
    sprintf(itPtr, "%llu", it);
    itPtrDec = atoll(itPtr);
    printf("it = 0x%X\n", itPtrDec);
    
    vec.push_back(123);
    it = vec.begin();
    memset(&itPtr, 0, 25);
    sprintf(itPtr, "%llu", it);
    itPtrDec = atoll(itPtr);
    printf("it = 0x%X\n", itPtrDec);
}

will print something like

it = 0x0

it = 0x2202E10

It's an incredibly hacky way to do it, but if you need it, it does the job. You will receive some compiler warnings which, if really bothering you, can be removed with #pragma


Vector is a template class and it is not safe to convert the contents of a class to a pointer : You cannot inherit the vector class to add this new functionality. and changing the function parameter is actually a better idea. Jst create another vector of int vector temp_foo (foo.begin[X],foo.end()); and pass this vector to you functions


For example, my vector<int> foo contains (5,2,6,87,251). A function takes vector<int>* and I want to pass it a pointer to (2,6,87,251).

A pointer to a vector<int> is not at all the same thing as a pointer to the elements of the vector.

In order to do this you will need to create a new vector<int> with just the elements you want in it to pass a pointer to. Something like:

 vector<int> tempVector( foo.begin()+1, foo.end());

 // now you can pass &tempVector to your function

However, if your function takes a pointer to an array of int, then you can pass &foo[1].


Use vector::front, it should be the most portable solution. I've used this when I'm interfacing with a fixed API that wants a char ptr. Example:

void funcThatTakesCharPtr(char* start, size_t size);

...

void myFunc(vector<char>& myVec)
{
    // Get a pointer to the front element of my vector:
    char* myDataPtr = &(myVec.front());

    // Pass that pointer to my external API:
    funcThatTakesCharPtr(myDataPtr, myVec.size());
}

I haven't tested this but could you use a set of pairs of iterators instead? Each iterator pair would represent the begin and end iterator of the sequence vector. E.g.:

typedef std::vector<int> Seq;
typedef std::pair<Seq::const_iterator, Seq::const_iterator> SeqRange;

bool operator< (const SeqRange& lhs, const SeqRange& rhs)
{
    Seq::const_iterator lhsNext = lhs.first;
    Seq::const_iterator rhsNext = rhs.first;

    while (lhsNext != lhs.second && rhsNext != rhs.second)
        if (*lhsNext < *rhsNext)
            return true;
        else if (*lhsNext > *rhsNext)
            return false;

    return false;
}

typedef std::set<SeqRange, std::less<SeqRange> > SeqSet;

Seq sequences;

void test (const SeqSet& seqSet, const SeqRange& seq)
{
    bool find = seqSet.find (seq) != seqSet.end ();
    bool find2 = seqSet.find (SeqRange (seq.first + 1, seq.second)) != seqSet.end ();
}

Obviously the vectors have to be held elsewhere as before. Also if a sequence vector is modified then its entry in the set would have to be removed and re-added as the iterators may have changed.

Jon


Your function shouldn't take vector<int>*; it should take vector<int>::iterator or vector<int>::const_iterator as appropriate. Then, just pass in foo.begin() + 1.


A vector is a container with full ownership of it's elements. One vector cannot hold a partial view of another, even a const-view. That's the root cause here.

If you need that, make your own container that has views with weak_ptr's to the data, or look at ranges. Pair of iterators (even pointers work well as iterators into a vector) or, even better, boost::iterator_range that work pretty seamlessly.

It depends on the templatability of your code. Use std::pair if you need to hide the code in a cpp.


If your function really takes vector<int> * (a pointer to vector), then you should pass &foo since that will be a pointer to the vector. Obviously that will not simply solve your problem, but you cannot directly convert an iterator to a vector, since the memory at the address of the iterator will not directly address a valid vector.

You can construct a new vector by calling the vector constructor:

template <class InputIterator> vector(InputIterator, InputIterator)

This constructs a new vector by copying the elements between the two iterators. You would use it roughly like this:

bar(std::vector<int>(foo.begin()+1, foo.end());

If you can, a better choice may be to change the function to take either an iterator to an element or a brand new vector (if it does not modify).

While you can do this sort of things with arrays since you know how they are stored, it's probably a bad idea to do the same with vectors. &foo[1] does not have the type vector<int>*.

Also, while the STL implementation is available online, it's usually risky to try and rely on the internal structure of an abstraction.


here it is, obtaining a reference to the coresponding pointer of an iterator use :

example:

string my_str= "hello world";

string::iterator it(my_str.begin());

char* pointer_inside_buffer=&(*it); //<--

[notice operator * returns a reference so doing & on a reference will give you the address].


The direct answer to your question is yes. If foo is a vector, you can do this: &foo[1].

This only works for vectors however, because the standard says that vectors implement storage by using contigious memory.

But you still can (and probably should) pass iterators instead of raw pointers because it is more expressive. Passing iterators does not make a copy of the vector.


Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to stl

Why is it OK to return a 'vector' from a function? How to remove all the occurrences of a char in c++ string How to use the priority queue STL for objects? use std::fill to populate vector with increasing numbers What does iterator->second mean? How to set initial size of std::vector? Sorting a vector in descending order How do I reverse a C++ vector? Recommended way to insert elements into map Replace an element into a specific position of a vector

Examples related to pointers

Method Call Chaining; returning a pointer vs a reference? lvalue required as left operand of assignment error when using C++ Error: stray '\240' in program Reference to non-static member function must be called How to convert const char* to char* in C? Why should I use a pointer rather than the object itself? Function stoi not declared C pointers and arrays: [Warning] assignment makes pointer from integer without a cast Constant pointer vs Pointer to constant How to get the real and total length of char * (char array)?

Examples related to vector

How to plot vectors in python using matplotlib How can I get the size of an std::vector as an int? Convert Mat to Array/Vector in OpenCV Are vectors passed to functions by value or by reference in C++ Why is it OK to return a 'vector' from a function? Append value to empty vector in R? How to initialize a vector with fixed length in R How to initialize a vector of vectors on a struct? numpy matrix vector multiplication Using atan2 to find angle between two vectors

Examples related to iterator

Iterating over Typescript Map Update row values where certain condition is met in pandas How to iterate (keys, values) in JavaScript? How to convert an iterator to a stream? How to iterate through a list of objects in C++ How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it? How to read one single line of csv data in Python? 'numpy.float64' object is not iterable Python list iterator behavior and next(iterator) python JSON only get keys in first level