Call Stack

김대익·2022년 2월 18일
0
#include <iostream>

int main() {
	int a;
    double b;
    
    return 0;
}

앞에서는 스택이 변수 a가 쌓인 뒤 b가 쌓인다고 했지만

실제 스택 메모리는 변수별로 메모리가 쌓이는 것이 아닌
stack frame별로 메모리를 쌓아간다.
이런 stack frame이 쌓이는 단위는 function call단위가 된다.

#include <iostream>
void foo() {
	int a;
    int b;
}

void bar() {
	Cat cat;
    Dog dog;
}

int main() {
	int a;
    double b;
    
    foo();
    bar();
    
    return 0;
}

라고한다면 맨 처음 main함수가 실행되면서 int a, double b의 stack frame이 만들어진다.
그 다음 foo함수의 stack frame이 올라가고
foo함수가 끝나면 foo함수의 stack frame이 사라지고
bar함수의 stack frame이 올라가고 bar함수가 끝나면 bar함수 stack frame이 사라지고
마지막으로 main함수의 stack frame이 사라진다.


stack frame에는 추가적인 정보를 가지고 있는데
인수와 return address정보이다.
인수는 foo(10)의 10,
return address는 function call이 끝나면 다음 명령어를 실행시켜주기 위해
다음 명령어가 들어있는 주소를 저장한 것이다.


class가 있을 때 stack frame으로 어떻게 나타내는지

class Cat {
public:
	Cat() {
    	m_age = 1;
    };
    ~Cat();
    void addAge(int arg) {
    	m_age += arg;
    };
private:
	int m_age;
}l

int main() {
	Cat cat;
    cat.addAge(10);
    
    return 0;
}

먼저 main함수의 stack frame이 생성되는데 Cat클래스의 int m_age를 위한 4bytes가 주어진다.
이후 Cat()생성자의 stack frame이 생성되고 main함수의 stack frame의 m_age=1로 initialize된다.
그리고 Cat()생성자에 main함수 function frame 메모리에 접근하기 위해 그 주소를 저장한다.
이후 stack frame이 free되고
addAge() 함수가 실행되면서 return instructor address와 arg인 10을 저장하고
main함수의 Cat클래스 메모리를 가르키는 this를 가지고 있는다.
addAge함수가 실행되면 인수인 10을 가지고 Cat클래스 메모리에 접근하여 m_age += 10을 실행한 뒤
~Cat()이 실행되어 Cat클래스가 free되면서 프로그램이 종료된다.

this는
stack frame이 쌓이면서 member variable을 컨트롤하기 위해
내부에 member variable을 가르키는 address가 들어있다고 생각하면 된다.

0개의 댓글