Where is the 'this' pointer stored in computer memory?

Where exactly is the 'this' pointer stored in memory? Is it allocated on the stack, on the heap, or in the data segment?

#include <iostream> using namespace std; class ClassA { int a, b; public: void add() { a = 10; b = 20; cout << a << b << endl; } }; int main() { ClassA obj; obj.add(); return 0; } 

In the above code, I call the add() member function and the receiver object is passed implicitly as the 'this' pointer. Where is this stored in memory?

+63
c ++ this-pointer
May 16 '13 at 10:54
source share
6 answers

Other answers did a very good job explaining how a typical compiler implements this (passing it as an implicit first parameter to a function).

I think it’s also useful to see what specifically says this in the C ++ ISO specification. According to the C ++ 03 ISO specification, & sect; 9.3.2 / 1:

In the body of a non-static (9.3) member function, the this is a non-lvalue expression whose value is the address of the object for which the function is being called.

It is important to note that this not a variable - it is an expression, much like the expression 1 + 2 * 3 is an expression. The value of this expression is allowed to be stored almost everywhere. The compiler can put it on the stack and pass it as an implicit parameter to the function, or it can put it in a register, and it can presumably put it in a heap or in a data segment. The C ++ specification intentionally gives the implementation some flexibility here.

I think the answer is "legal language" - "this is a complete implementation, and, moreover, this not technically a pointer, but an expression that evaluates a pointer."

Hope this helps!

+63
May 16 '13 at 15:54
source share

The easiest way is to think of this as a hidden optional argument, which is always passed automatically.

So, a fictional method like:

 size_t String::length(void) const { return strlen(m_string); } 

actually more like a hood:

 size_t String__length(const String *this) { return strlen(this->m_string); } 

and a call like:

 { String example("hello"); cout << example.length(); } 

becomes something like:

 cout << String__length(&example); 

Please note that the above conversion is simplified, we hope that my point will become more clear. No need to fill in the comments "whaaa, where is the sort to overload the method, right?" - like objections, please. :)

This turns the question into β€œwhere are the arguments stored?” And the answer, of course, β€œdoes it depend.” :)

This is often on the stack, but it can also be in registers, or any other mechanism that the compiler considers useful for the target architecture.

+78
May 16 '13 at 10:56
source share

this usually passed as a hidden method argument (the only difference in all the different calling conventions is how).

If you call:

 myClass.Method(1, 2, 3); 

The compiler generates the following code:

 Method(&myClass, 1, 2, 3); 

Where the first parameter is actually a pointer to this .

Let me check the following code:

 class MyClass { private: int a; public: void __stdcall Method(int i) { a = i; } }; int main(int argc, char *argv[]) { MyClass myClass; myClass.Method(5); return 0; } 

Using __stdcall , I made the compiler pass all the parameters through the stack. If you then run the debugger and check the build code, you will find something like the following:

  myClass.Method(5); 00AA31BE push 5 00AA31C0 lea eax,[myClass] 00AA31C3 push eax 00AA31C4 call MyClass::Method (0AA1447h) 

As you can see, the method parameter is passed through the stack, then the address myClass is loaded into the eax register and pushed onto the stack again. In other words, this considered as a regular parameter of this method.

+33
May 16 '13 at 10:59
source share

this is an rvalue (you cannot take its address), so it does not (necessarily) take up memory at all. Depending on the compiler and the target architecture, it will often be in the register: i0 on Sparc, ECX from MSVC to Intel, etc. When the optimizer is active, it can even move around. (I saw this in different registers with MSVC).

+18
May 16 '13 at 11:28
source share

this behaves mainly as an argument to the function and, as such, will be stored on the stack or - if binary conventions of architecture calls allow this - in the register.

+9
May 16 '13 at 10:57
source share

this not stored in a specific place! The object to which it points is stored somewhere and has a clearly defined address, but the address itself does not have a specific home address. This was reported in the program. Not only that, but there may be many copies of this index.

In the following imaginary function init an object is registered to receive events and timer callbacks (using imaginary event source objects). So, after registration, there are two more copies of this :

 void foo_listener::init() { g_usb_events.register(this); // register to receive USB events g_timer.register(this, 5); // register for a 5 second timer } 

I have a function activation chain, there will also be several copies of this pointer. Suppose we have an obj object and call it the function foo . This function calls the same function bar , and bar calls another function called update . Each activation level of each function has a this pointer. It is stored in a machine register or in a memory cell in the frame of the function activation stack.

0
May 16 '13 at 15:08
source share



All Articles