1

I am trying to create an object that lives in a struct and pass that struct to another object while pointing to the same address. Here is a minimal example of what I am trying to do:

#include <iostream>

class A {
};

struct S {
  A* a;
  S(A* c) { a = c; }
};

class B {
  public:
    B(S* s){ s_ = s; }
    S* get_s() {return s_;}
  private:
    S* s_;
};

int main() {
  A* a = new A();
  S* s = new S(a);
  B b =  B(s);

  std::cout << "a in A = " << &a << "\n";
  std::cout << "a in S = " << &s->a << "\n"; 
  std::cout << "a in B = " << b.get_s() << "\n";

  //output:
  // a in A = 0x7ffe81376918
  // a in S = 0x2563e90
  // a in B = 0x2563e90
}

I am expecting for all a to point to the same address.

FED
  • 23
  • 3
  • 3
    `&a` is the address of the `A*` pointer you've made to point to an `A`. If you wanted the address of the `A` you're pointing to, you'd just do `std::cout << a`. – scohe001 Jul 24 '19 at 21:20
  • You've only created three objects and all of them 'live' in main. Everything else is pointers. If you want to create an object that lives inside another one don't use pointers. – john Jul 24 '19 at 21:20

2 Answers2

2

Let's walk through your outputs one by one...

std::cout << "a in A = " << &a << "\n";

&a is the address of the A* pointer you've made to point to an A. If you wanted the address of the A you're pointing to, you'd just do std::cout << a.

std::cout << "a in S = " << &s->a << "\n";

s->a gets us a pointer to an A, or the address of an A. Getting the address of that pointer is going a step backwards. Just s->a is enough here.

std::cout << "a in B = " << b.get_s() << "\n";

b.get_s() is going to give you the address of your S* member. You probably wanted b.get_s()->a.

Altogether, your outputs should look like:

  std::cout << "a in A = " << a << "\n";
  std::cout << "a in S = " << &s->a << "\n"; 
  std::cout << "a in B = " << b.get_s()->a << "\n";

This gives the following for me on ideone:

a in A = 0x5638893cac20
a in S = 0x5638893cac20
a in B = 0x5638893cac20
Community
  • 1
  • 1
scohe001
  • 15,110
  • 2
  • 31
  • 51
0

A pointer is a variable that contains the address of some other memory object. A pointer (not a class such as unique_ptr but rather the pointer type carried over from C such as you are using) is a simple, Plain Old Data type. See What are POD types in C++? for that topic as well as the various links such as What are Aggregates and PODs and how/why are they special?

Once you allocate the memory for some object and assign it to a pointer variable, the address value can be copied to other pointer variables. Doing so means that all of the pointer variables, the original as well as the copies, will have the same value meaning containing the same address.

If you have a struct with such a pointer variable as a member, it works the same way so long as the pointer variable member is not modified in some way. An assignment of a simple struct will just make a copy so the original pointer value just gets copied.

Here is a modified version of your posted source with a few corrections as well as annotations.

#include <iostream>

class A {
};

struct S {
  A* a_s;        // pointer variable for the address of an A
  S(A* c) { a_s = c; }   // constructor takes the value of pointer variable c and assigns it to struct member pointer variable a_s
};

class B {
  public:
    B(S* s){ s_b = s; }
    S* get_s() {return s_b;}
  private:
    S* s_b;
};

int main() {
  A* a = new A();     // construct a new A and assign the address to pointer variable a
  S* s = new S(a);    // construct a new S and provide it the address of the A constructed
  B b =  B(s);        // construct a new B and provide it the address of the S constructed

  // at this point we have the following memory objects.
  //    - an instance of the class A whose address is in a pointer variable "a"
  //    - an instance of the struct S whose address is in a pointer variable s
  //      . the instance's pointer variable "a_s" contains the same value as the local variable "a"
  //    - an instance of the class B which contains a pointer to the struct variable "s"

  // so at this point we have five objects in memory, two constructed with new and three local variables:
  //  - an instance of the class A the address of which is in the local pointer variable "a"
  //  - an instance of the struct S the address of which is in the local pointer variable "s"
  //  - an instance of the class B which is a local variable "b" that is "on the stack"

  // we also have two copies of the address of the class A object which was created:
  //  - the local variable "a"
  //  - the struct S member "a_s" of the object whose address is in local variable "s"

  // we also have two copies of the address of struct S object which was created:
  //  - the local variable "s"
  //  - the class B member "b_s" of the instance in local variable "b"

  // since the class B instance in local variable "b" has a pointer to the struct S whose
  // address is in local variable "s" then the instance doesn't contain a copy of that
  // instance of struct S however it does contain a copy of the address that is contained in the
  // local variable "s".


  std::cout << "a in A = " << a << "\n";         // print the value of the pointer variable "a"
  std::cout << "a in S = " << s->a_s << "\n";      // print the value of the pointer variable "a_s" that is a member of the struct S instance "s"
  std::cout << "a in B = " << b.get_s()->a_s << "\n";  // print value of pointer "a_s" that is a member of struct S instance whose address is in "b.s_b"

  return 0;
}

which has an output of:

a in A = 008322D8
a in S = 008322D8
a in B = 008322D8
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106