0

I have a question. Let's say that I have a struct, say something like:

struct myData
{
    int a;
    int b
} x, y ;

Then, I create a pointer that points to x, for example:

myData * x_ptr = &x;

So I know that x_ptr point to the memory location where x is stored. So I can find the memory location for the whole struct. But, let's say I want to find the memory location for the member a of the struct variable x. How do I do that ?

For me, it would seem natural to do something like this:

x_ptr.a

Now, I know that this dosen't work. When I imagine how the variables are stored in the memory of the computer I'm thinking of a box with something in it. So for a struct, it would be a bigger box which contains two members, in my case a and b. So, is the memory location of a and b the same as the memory location for the whole "box" ? That's why I can't acces the memory location of x.a ?

I'm trying to understand pointers, and I quickly gained an idea of how things work, but this bothers me. Could somebody answer me, please ? Thank you! :)

BarbuDorel
  • 193
  • 1
  • 1
  • 5
  • 2
    `x_ptr->a` is the correct syntax in C++. – Roger Rowland Dec 15 '13 at 20:02
  • You can read about the historical backgrounds of `->` in [this question](http://stackoverflow.com/q/13366083/420683). – dyp Dec 15 '13 at 20:03
  • In this case, the address of `x` is also required to be the address of `x.a`. No padding is allowed before the first element of a struct, and a pointer to a struct, suitably converted, must also be a pointer to the first element of that struct. – Jerry Coffin Dec 15 '13 at 20:04

6 Answers6

1

It is simple

the memory location of a is &x_ptr->a;

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0
int *x_a_ptr = &(x_ptr->a);

Now x_a_ptr is a pointer to the a that is part of the struct that x_ptr points to.

I think it's probably likely that in this case the value of x_ptr and x_a_ptr might be the same. But if you got a pointer to b, it'd have a value different from x_ptr.

And by the way, instead of &(x_ptr->a), you could just do &(x.a).

nhgrif
  • 61,578
  • 25
  • 134
  • 173
0

For POD types (POD means Plain Old Data), struct members are usually laid out linearly in memory, sometimes with padding between members to meet the alignment constraints of the types.

In your example, x_ptr points to the first byte of the struct, as well as the first member of the struct. Indeed, you're allowed do convert a pointer-to-struct to pointer-to-first-member-of-struct safely.

Under the hood, when you say x_ptr->a or x_ptr->b, the compiler adds an offset to the pointer before dereferencing it, based on the layout of the struct.

You can get a direct pointer to a member of a struct by saying &(x.a) or &(x.b).

Joe Z
  • 17,413
  • 3
  • 28
  • 39
0

The rules for classes and structs regarding their memory structure is fairly straight-foward:

myData * x_ptr = &x; // pointer to x
x_ptr->a = 5; // sets a to 5
int* a = (int*)&x; // since a is the first element, this will set a to the address of x.a
int* b = &(x.a); // this will also give you the address of x.a
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
0

If you want to find the address of a subobject, you can just take the address of the subobject, e.g.:

&x.a

or

&x_ptr->a

If you want to take sort of the address of a relative to a pointer, you could use

int myData::*a_ptr = &myData::a;

This defines a pointer-to-member which can be used with an object or a pointer to access the member, e.g.

int val0 = x.*a_ptr;
int val1 = x_ptr->*a_ptr;

If these don't make any sense just ignore pointer-to-members for now (they show up rarely in real-life, partly because hardly any C++ programmer knows about them).

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
0

As said by others it is &(x_ptr->a). To explain what's going on, you have to understand whether an expression is a pointer or not, and how to move between the two. Here are a few example to get some intuition:

myData dataOnStack; // dataOnStack lives on the stack
int a = dataOnStack.a; // we can directly reach for members

// this is just a pointer to struct we made earlier
myData * dataPtr = &onStack;

// here we dereference the pointer, and copy to the stack
myData copyOnStack = *dataPtr;

// again we can directly reach inside our copy
a = copyOnStack.a

// given a pointer, we can dereference and reach inside it using ->
// here, the whole expression dataPtr->a is not a pointer, because
// we have dereferenced dataPtr.
a = dataPtr->a;

// to finally answer your question, we can move back to the "pointer world"
// by taking the address of the previous expression
int* aPtr = &(dataPtr->a);

// alternatively, instead of going through the pointer, since
// we have the original struct on the stack we can just do this:
aPtr = &dataOnStack.a;
Alexander Kondratskiy
  • 4,156
  • 2
  • 30
  • 51