ProgramingTip

'this'포인터는 컴퓨터 메모리에 어디에 저장합니까?

bestdevel 2020. 11. 22. 20:23
반응형

'this'포인터는 컴퓨터 메모리에 어디에 저장합니까?


'this'포인터는 정확히 어디에 메모리에 저장? 스택, 힙 또는 데이터 세그먼트에 할당?

#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;
}

위의 코드에서 멤버 함수를 호출하고 add()당사자 개체는 'this'포인터로 암시 적으로 전달됩니다. this에는 메모리 어디에 저장됩니까?


다른 답변은 일반적인 컴파일러가 구현하는 방법을 설명하는 매우 좋은 작업을 수행했습니다 this(함수에 암시 적 첫 번째 매개 변수로 전달하여).

C ++ ISO 사양이 이것에 대해 명시 적으로 말하는 것을 보는 것도 유용하다고 생각합니다. C ++ 03 ISO 사양, §9.3.2 / 1에 따르면 :

비 정적 (9.3) 멤버 함수의 본문에서 키워드 this는 값이 함수가 호출되는 객체 주소 인 비 lvalue 어디에입니다.

그것은 그 노트에 중요 this하다 하지 변수-그것은 표현 많이 표현하는 것과 같은 방식으로 1 + 2 * 3표현입니다. 이 경우에는 거의 모든 곳에 저장할 수 있습니다. 컴파일러 수도 스택에 선언 할 함수에 내재라고 전달할 함수에, 그 있습니다. C ++ 사양은 의도적으로 구현에 약간의 유연성을 제공합니다.

"언어 변호사"의 대답은 "이것은 완전히 구현에 정의되어 있고 this기술적으로 포인터가 아니라 포인터로 평가되는"이라고 생각합니다.

도움이 되셨기를 바랍니다!


가장 쉬운 방법 this은 항상 자동으로 전달되는 숨겨진 인수로 생각하는 것입니다 .

따라서 다음과 같은 가상의 방법이 있습니다.

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

실제로는 다음과 가능합니다.

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

다음과 같은 전화 :

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

다음과 같이됩니다.

cout << String__length(&example);

위의 변환이 단순화되어 내 요점이 더 명확하게 해지기를 바랍니다. "와우 없습니다, 메소드 오버로딩에 대한 마샬링은 어디입니까?"라는 유형의 이의로 주석을 채울 필요가 있습니다. :)

그것은 질문을 "인수가 저장되는 위치"로 바꾸고, 대답은 당연히 "따라"입니다. :)

스택에있는 경우가 많지만 많은 경우에도 사용할 수 있거나 대상 아키텍처에 적합하거나 다른 스택이있을 수 있습니다.


this일반적으로 메서드의 숨겨진 인수로 전달됩니다 (다른 호출 규칙에서 유일한 차이점은 방법입니다 ).

전화하는 경우 :

myClass.Method(1, 2, 3);

컴파일러는 다음 코드를 생성합니다.

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

첫 번째 매개 변수는 실제로에 대한 포인터 this입니다.

다음 코드를 확인해 보겠습니다.

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;
}

사용 가능한 __stdcall컴파일러가 모든 매개 변수를 스택을 통해 전달했습니다. 그런 다음 디버거를 시작하고 어셈블리 코드를 검사하면 다음과 같은 것을 사용할 수 있습니다.

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

보시다시피, 메소드의 매개 변수가 스택을 통해 전달 된 다음 myClass의 주소가 eax 레지스터에로드되고 다시 스택에 푸시됩니다. 즉, this이 메소드의 일반 매개 변수로 처리됩니다.


thisrvalue (주소를 사용할 수 없음)이므로 메모리를 전혀 차지하지 않습니다. 컴파일러 및 대상 아키텍처에 따라 종종 레지스터에 있습니다. Sparc의 i0, Intel의 MSVC가있는 ECX 등. 최적화 프로그램이 활성화되면 이동할 수도 있습니다. (MSVC의 다른 레지스터에서 본 적이 있습니다).


this 대부분 함수 인수처럼 동작하므로 스택에 저장되거나 아키텍처의 이진 호출 규칙이 허용하는 경우 레지스터에 저장됩니다.


this잘 정의 된 위치에 저장되지 않습니다! 가리키는 객체는 어딘가에 저장되고 잘 정의 된 주소를 가지고 있지만 주소 자체에는 특정 집 주소가 없습니다. 프로그램 내에서 소통됩니다. 뿐만 아니라 그 포인터의 사본이 많이있을 수 있습니다.

다음 가상 init함수에서 객체는 가상 이벤트 소스 객체를 사용하여 이벤트 및 타이머 콜백을 수신하기 위해 자신을 등록합니다. 따라서 등록 후 두 개의 추가 사본이 있습니다 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
}

나는 함수 활성화 체인이며 this 포인터의 여러 복사본이 있습니다. 객체가 obj있고 그 foo함수를 호출 한다고 가정 합니다. 이 함수는 동일한 객체의 bar함수를 bar호출 하고 라는 다른 함수를 호출 update합니다. 각 기능 활성화 수준에는 this포인터가 있습니다. 기계 레지스터 또는 기능 활성화 스택 프레임의 메모리 위치에 저장됩니다.

참고 URL : https://stackoverflow.com/questions/16585562/where-is-the-this-pointer-stored-in-computer-memory

반응형