开发者

trouble with memory allocation for a class member vector, given an array of objects of that class?

开发者 https://www.devze.com 2023-02-12 07:17 出处:网络
My basic program structure is this: class B1 { vector <someStruct> aStruct; //some struct contains a vector of \'someotherStruct\'s, etc

My basic program structure is this:

class B1 
{
    vector <someStruct> aStruct; //some struct contains a vector of 'someotherStruct's, etc
    B1() { cout << &aStruct << " ";};
};


class B2 {B1* pB1;};

class A
{
    B1 object_B1;
    B2 object_B2;

    A() { objectB2.pB1 = &object_B1;}; 
开发者_运维百科};

int main()
{
    vector <A> someA;
    for(int q=0; q < N; q++)
        someA.push_back(A()); 

    cout << endl;

    for (int q=0; q < N; q++)
        cout << someA[q].B2.pB1 << " ";
}

So if N was 5, the output would be: 0xbffff828 0xbffff828 0xbffff828 0xbffff828 0xbffff828 \n

0xbffff828 0xbffff828 0xbffff828 0xbffff828 0xbffff828

In other words, each object's vector occupies the same space in memory. And program output bears this out as well, since accessing data in the vector through different objects gives the same values, even when they should be different. The other weird thing, of course, is it gives me the same address for the vector as for the object.


Ignoring the large number of errors in the program...

A.push_back(A());

This creates a temporary object of type A. The object_B2.pB1 member variable is initialized to point to the object_B1 member variable of this temporary object.

This temporary A object is then copied into the someA container. The address of this copy's object_B1 member variable is different, but you don't update the object_B2.pB1 member variable to point into the new instance. To do this, you would need to implement a copy constructor (and, for correctness, you would also need to implement a copy assignment operator).

The reason that all of the pointers end up being the same is that the temporary objects are all created in the same location in memory, which makes since, since you are presumably calling push_back in a loop, so the temporary object can be created on the stack in the same place at each iteration through the loop.


You are missing a copy ctor for A and the default copy semantics copy the pointer value from one B2 object to another. Each item in the struct sees the same address because they are all copied from the same source object. When this pointed-to object is later destroyed, you'll have UB accessing it.

A a1;
A a2 = a1;
assert(a2.object_B2.pB1 == &a1.object_B1);  // Danger Will Robinson!

The fix:

struct A {
  B1 object_B1;
  B2 object_B2;

  A() { objectB2.pB1 = &object_B1; }
  A(A const &x)
  : object_B1 (x.object_B1)
  {
    object_B2.pB1 = &object_B1;
  }
};

You also need a copy-assignment operator because the default one has a similar problem. Declare this op= as private without defining it if you want it disabled.

0

精彩评论

暂无评论...
验证码 换一张
取 消