3

I'm having a memory violation error and I don't know where it comes from. My question is : am I allowed to get the address of a class member while inside the constructor initialization list so that I can pass it to an object that needs a reference to it ?

For example :

class A
{
};

class ReferencesA
{
    A * const pA;

    ReferencesA( A * ptrA ) : pA( ptrA ) { }
};

class B
{
    A a;

    ReferencesA referencesA;

    B() : referencesA( & a ) { }
};

Is is safe to & a inside the constructor initialization list ? It seems to me that it would be, but things don't always work like we expect.

Thank you.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
Virus721
  • 8,061
  • 12
  • 67
  • 123
  • Looks ok to me. It could be what "referencesA" does with the ptrA inside its ctor that is causing the crash, Especially if "a" has not been constructed yet. – rakeshdn Nov 03 '15 at 15:57

1 Answers1

2

The order of the initialisation of the base members in class B is a, then referencesA. That's because they appear in that order in the class declaration. (The order in which they appear, if at all, in the initialisation list in your constructor is not relevant.)

So using &a to initialise referencesA is safe, if a little brittle. In your case, &a is the address of the default-constructed member a.

I'd advise against coding like this in case someone changes the order of the members in your class.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 2
    Thanks. The problem is that, if i want to have const pointers (or references) to indicate that the pointer will be the same and valid for the whole lifetime of the object, then i need to initialize things in the initializer list, else i can't use const. – Virus721 Nov 03 '15 at 15:56
  • 5
    It's worth noting that saving a pointer to an uninitialized object is safe, so the order in the class doesn't matter. `a` only has to be first in the class list if you want to _read or write_ through the pointer. – Mooing Duck Nov 03 '15 at 16:00
  • 1
    @MooingDuck do you have a reference for that? – haelix Nov 28 '18 at 15:47
  • 1
    @haelix: I don't, but it's so common that you'd have to think about it to even realize that's what we've all been doing. `char buffer[30]; memset(buffer, 0, 30);` No one would argue that it's undefined behavior to pass the pointer to uninitialized memory to `memset`. When you call a member method from a constructor, that also does it, because it passes an implicit `this` pointer to the method but the derived constructors haven't been called yet. Heck even `int x; std::cin >> x;` passes a reference to uninitialized memory. – Mooing Duck Nov 28 '18 at 17:40
  • 1
    @MooingDuck Ah ok I meant specifically constructing members using addresses/references of members coming later in declaration order. I looked for a reference and couldn't find anything (class.base.init). I can only think it's OK given `this` is accessible and offsets should have been computed. – haelix Nov 28 '18 at 18:06