Home > Net >  Creating and storing objects in a container without using new?
Creating and storing objects in a container without using new?

Time:05-18

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);
}
  • Related