0

basically, I wrote a class with another class array atributte inside, I mean:

class MyClass
{
  unsigned long long x_;
  bool y_;

  public:
  MyClass & operator=(const MyClass & mc)
  {
    x_ = mc.x_;
    y_ = mc.y_;
    return *this;
  }
};

class MyOtherClass
{
  MyClass myClass_[9];

  public:
  MyOtherClass & operator=(const MyOtherClass & mc)
  {
    for (unsigned int i = 0; i < 9; i++)
    {
      myClass_[i] = mc.myClass_[i];
    }
    return *this;
  }
};

all of this implemented in a shared library.

I use second class in a second library like:

void ThridClass::foo( )
{
  MyOtherClass c1;
  MyOtherClass c2;
  c1 = c2;
}

in a 64bit compilation mode with xlC_7, with no alignment pragmas, no optimization, non virtual functions, etc, running on an Aix system.

These are the compiler options I used in both libraries:

-q64 -bernotok -g -M -qflag=i:w

and these are linker options:

-brtl -bernotok -G

When I debug the program using dbx and ask for c1.myClass_[0] address I got one value. But, if I strace the execution inside MyOtherClass.operator=() function, I get another address for this attribute pointer.

(dbx) p &c1.myClass_[0]
0x0ffffffffffe6a20
(dbx) s
stopped in operator=(const MyOtherClass &)
(dbx) p &myClass_[0]
0x0ffffffffffe69c0

This problem doesn't apperar on Linux and works fine.

Any idea?

iammilind
  • 68,093
  • 33
  • 169
  • 336
Tio Pepe
  • 3,071
  • 1
  • 17
  • 22
  • 1
    What is the "problem" you're talking about? Does it crash or give unexpected results? – Seth Carnegie Sep 08 '11 at 11:24
  • Both, if the array is big enough, the stack frame crash and core is dumped because any asignment inside the operator=( ) function is made in smaller address. – Tio Pepe Sep 08 '11 at 11:36
  • that's just a consequence of having too many objects on the stack, resulting in a stack overflow. I don't know what you mean by "any assignment inside the operator=( ) function is made in smaller address" though. – Seth Carnegie Sep 08 '11 at 11:39
  • My initial guess is that somehow something changed from the time you built the shared library to when you built the executable. Or there is something funny in your header that both are using. – Dave S Sep 08 '11 at 11:43
  • @Seth Sorry: Outside the operator=( ) function, each array item has correct address. But, inside operator=( ) function, each array item has a smaller address: Outside the operator=( ) &c1.myClass_[0] = 0x0ffffffffffe6a20 &c1.myClass_[1] = 0x0ffffffffffe6a30 &c1.myClass_[2] = 0x0ffffffffffe6a40 and so on, but inside the operator= function, adresses point to smaller address: &c1.myClass_[0] = 0x0ffffffffffe69c0 &c1.myClass_[1] = 0x0ffffffffffe6890 &c1.myClass_[2] = 0x0ffffffffffe67a0 ... if there are a lot of items, address became over stack frame and corrupts it – Tio Pepe Sep 08 '11 at 11:58

2 Answers2

1

Just ditch your copy assignment and copy constructor definitions- the implicit compiler-generated ones will be more than sufficient.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • Quick question: for a compiler-generated assignment operator for classes that have arrays of objects which have an _explicit_ assignment operator, is the assignment operator of each of those objects called when the parent object is assigned? Or does it just do a bitwise copy of the memory of the array? – Seth Carnegie Sep 08 '11 at 11:36
  • @Seth: It calls `operator=`. All the special member functions are defined recursively. – Puppy Sep 08 '11 at 12:10
  • I wrote a quick test and seems like it doesn't call the `operator =` of the objects inside... I wonder now how all my programs worked when I had a `vector` in my class and I copied the class around without copy constructor! (Or maybe I always either wrote the copy constructor or passed around by reference. It must have come to me naturally) – Shahbaz Sep 08 '11 at 12:14
  • @Shahbaz: The language will not do a bitwise copy. You likely just wrote a flawed test where the copy was ellided by RVO/NRVO. – Puppy Sep 08 '11 at 21:44
  • @DeadMG, since I can't write the code here, I will edit your post, put it there for you to see and you can reject the edit if you want. – Shahbaz Sep 09 '11 at 13:16
0

In your operator= you return inside the loop

MyOtherClass & MyOtherClass::operator=(const MyOtherClass & mc)
    {
        for (unsigned int i = 0; i < 9; i++)
        {
            myClass_[i] = mc.myClass_[i];
            return *this; ////                Move this outside the loop.
        }
    }
DanS
  • 1,677
  • 20
  • 30