Reputation:
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.
Upvotes: 5
Views: 5015
Reputation: 6174
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.
Upvotes: 0
Reputation: 19331
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:
list
rather than a vector
.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).
Upvotes: 1