5
struct Struct_t {
    int Value1;
    int Value2;
};

vector<Struct_t> Struct;
Struct.resize(10, Struct_t());

for (int i = 0; i < 10; ++i)
{    
    Struct[i].Value1 = (i + 10) * 3;
    Struct[i].Value2 = (i + 5) * 2;
}

How can I create a pointer to Struct[i]?

What I want to do essentially is something like this, but I'm sure this can be done better:

int value = 6;
Struct_t temp = Struct[value], *s;
s = &temp;

s->Value1 = 42;
s->Value2 = 6;

Main goal is, that I can easily create a pointer to Struct[n] with 1 line/function.

Cloud
  • 17,212
  • 12
  • 64
  • 137
  • Doing such an operation will result in pointers to invalid iterators. – Cloud Aug 13 '15 at 04:19
  • 1
    Have you considered using a reference instead? Example `Struct_t& tmp = Struct[value]; tmp.Value1 = 23;`. The mentioned warnings about dangling pointers below apply still, only use that in a restricted scope where you know that the vector will not be reallocated. – Ulrich Eckhardt Aug 13 '15 at 04:37

2 Answers2

1

So far, the provided answers are missing the elephant in the room. You could create a pointer to a vector element like so:

(Fault-prone) Code Listing


#include <iostream>
#include <vector>

struct Struct_t {
    int Value1;
    int Value2;
};

int main(void)
{
    std::vector<Struct_t> sVec;
    sVec.resize(10, Struct_t());

    int count = 0;
    for (std::vector<Struct_t>::iterator vIt = sVec.begin(); vIt != sVec.end(); ++vIt)
    {    
        vIt->Value1 = (count + 10) * 3;
        vIt->Value2 = (count + 5) * 2;
        count++;
    }

    Struct_t* pStruct = &sVec[5];

    std::cout << "sVec[5] = (" << pStruct->Value1 << "," << pStruct->Value2
        << ")" << std::endl;

    return 0;
}

Sample Output


sVec[5] = (45,20)

However, vector is not an abstract type you want to use if you will be generating pointers to individual elements of the vector/"array". When the vector needs to be re-sized (shrink or grow), the iterators are invalidated, so your pointers will point to now-freed memory, crashing your program. If you want to have raw pointers directly to vector elements, you want to first:

  1. Use a list rather than a vector.
  2. Possibly use managed pointers to handle reference counts.

Finally, when dealing with template classes like vector, list, hash_table, etc, you should try to get used to using the iterator example I used above, as you don't have to worry about checking for exceptions when using an invalid index (the overloaded [] operators can throw exceptions, unless you replace them with the .at() member function instead for element access).

Community
  • 1
  • 1
Cloud
  • 17,212
  • 12
  • 64
  • 137
  • It's perfectly fine to access data representation of an container, if there are no API operations in between. In that case, the internal pointer does not change by itself. – Grzegorz Szpetkowski Aug 13 '15 at 04:25
  • @GrzegorzSzpetkowski But it's not a safe habit/style to get into in the first place. Also, if TC/OP is asking for help on how to generate a raw pointer to a vector element, he/she will likely be unfamiliar with iterator invalidation, and it could bite them in the future. – Cloud Aug 13 '15 at 04:27
  • From that point of view, you are right. I assumed that OP has already some basic knowledgle of STL containers. – Grzegorz Szpetkowski Aug 13 '15 at 04:29
  • @GrzegorzSzpetkowski Fair enough. I almost never DV answers unless I'm trying to draw attention to them. My apologies if it seemed flippant. – Cloud Aug 13 '15 at 04:31
0

For a std::vector, &v[i], gives you a pointer to the i'th element. Your sample code becomes:

int value = 6;
Struct_t* s = &Struct[value];

s->Value1 = 42;
s->Value2 = 6;

So the one-liner is Struct_t* s = &Struct[value];

There is nothing wrong with doing this, but like most aspects of C++, you need to understand what you are doing. The above code is perfectly valid and guaranteed by the standard. (Also note that the code in this answer avoids an error in the original code where s was a pointer to a temporary copy and no changes were made to the contents of the Struct vector.)

Yes, resizing Struct will invalidate any pointers made before the resize, and yes, using iterators is often a better technique. But this is a correct and reasonable answer to the original question.

Phil
  • 4,762
  • 1
  • 27
  • 53