Pointer to a member variable

The next output of the program is always 1 1 1. In the book “Inside the C ++ Object Model Model” it is mentioned that it will give an offset. The goal is also to find the layout of the object. But I'm confused with the exit. Used by g ++ 4.5.2

class Test { public: float a; float b; float c; }; int main() { float Test::*ptr = &Test::a; float Test::*ptr1 = &Test::b; float Test::*ptr2 = &Test::c; cout<<ptr<<endl; cout<<ptr1<<endl; cout<<ptr2<<endl; return 0; } 

Output:

 1 1 1 

Edit (next question): The book mentions that origin.y = 0 can be converted to &origin + (Point3d::y-1) , where origin is a Point3d object and y is a member variable of the Point3d class. Although, when I compiled, it gave me a compilation error.

+4
source share
2 answers

You wrote that you want to find the memory offset. Although what FredOverflow writes in its entirety, you must make an instance of your Test class if you want to know the addresses a , b and c . For instance:

 Test t; float *ptr = &t.a; float *ptr1 = &t.b; float *ptr2 = &t.c; 

On my machine, this gives the following three addresses:

 0x7fff564f8918 0x7fff564f891c 0x7fff564f8920 

And you will notice that they are 4 bytes (or sizeof(float) ) and the size of Test is 12 bytes (using sizeof(Test) ). In addition, the &t address is 0x7fff564f8918 the same &t.a address. How the memory layout of an instance of the Test class is formed.

You can also find the offset of members of type POD with offsetof() .

 cout << offsetof(Test, a) << endl; cout << offsetof(Test, b) << endl; cout << offsetof(Test, c) << endl; 

Productivity

 0 4 8 

Note that offsetof(Test, b) is essentially the same as

 (unsigned long long) &(((Test*) 0)->b) - (unsigned long long) (Test*) 0 

Answer the following question:

This code will not work due to the same errors that were mentioned earlier. However, if you want to calculate the address of your y member origin and set it to 0 , you can do this as follows:

 class Point3d { public: float x, y, z; }; Point3d origin; origin.y = 10; // We take the address of origin, which points to the first member, // then add the offset to the member y. float *ptr = (float*) ((unsigned long long) &origin + offsetof(Point3d, y)); cout << "Old value: " << *ptr << endl; *ptr = 0; cout << "New value: " << *ptr << endl; 

Sets the output:

 Old value: 10 New value: 0 

Again, remember that this is only possible because Point3d is a type of POD .

+4
source

You cannot print pointers to elements, but pointers to members can be implicitly converted to bool , and they can be printed, of course. A null pointer is converted to false , and all other pointers are converted to true . By default, std::cout prints false as 0 and true as 1 .

+16
source

All Articles