Say I have the class
class A{
int value;
public:
A(int val) : value(val) {};
}
I store pointers of instances in a collection such as vector using for loop
std::vector<A*> myCollection;
for (int i = 0; i < 10; i){
myCollection.push_back(&A(i));
}
Now the for loop will construct and destruct an object at the same memory location resulting in a vector with 10 pointers pointing to the same address and dereferencing them will give A->value = 9. Is there any way around this without dynamic allocation? And yes I have to use collection of pointers and not references.
CodePudding user response:
If the objects need to be on the stack, but you also want a vector of pointers because of some API requirement, etc., Just create an array of the objects, then store the pointers. Be very mindful of the lifetime issues.
size_t const sz = 3;
A arr[sz] {1, 2, 3};
std::vector<A*> v;
v.reserve(sz);
for (auto& a : arr) v.push_back(&a);
someFunc(v);
CodePudding user response:
The problem with your current program is that A(i)
is a prvalue and hence its address using the &
operator cannot be taken. This means that the following expression is invalid in your code:
//---------------------vvvvv----->invalid because A(i) is a prvalue
myCollection.push_back(&A(i));
You could instead use a std::vector<A>
in addtion to std::vector<A*>
as shown below:
std::vector<A> myVector;
myVector.reserve(10);
//-------^^^^^^^---------------->to avoid reallocations when capacity is not enough
for (int i = 0; i < 10; i){
myVector.emplace_back(i);
//-----------^^^^^^^^^^^^------->use emplace_back to forward the argument i
}
std::vector<A*> myPtrVector;
myPtrVector.reserve(10);
for(auto&elem: myVector)
{
myPtrVector.push_back(&elem);
}