Coding Memo

함수 호출 in stack 본문

etc

함수 호출 in stack

minttea25 2023. 6. 25. 15:36

먼저 메모리의 구조는 다음과 같다는 것을 확인하고 넘어가자.

메모리 구조

 

stack에는 지역변수와 함수 호출 정보가 저장되어 있고 스택의 자료구조로 되어 있다.

여기서 함수 호출 정보가 무엇을 의미하는지 확인해보자.


함수 호출 스택

 

예시로 사용할 코드이다.

int func1(int a)
{
	int b;
	b = a * a;
	return b;
}

int main()
{
	int i = 0;
	char* s;

	s = new char[1024];
	i = func1(i);

	delete[] s;

	return 0;
}

 

 


main

 

먼저 main 함수가 로드 되었을 때의 메모리 상태이다.

main

main 함수의 지역 변수 i와 s가 스택에 들어가게 된다.

 

 

frame pointer: 현재 함수의 스택 프레임을 추적하기 위해 컴퓨터 프로세서에서 사용하는 메모리 위치, 함수가 호출되면 함수 인수, 반환 주소 및 지역 변수등의 정보를 가지고 분리하기 위해 새 스택 프레임이 생성되고 프레임 포인터는 현재 함수의 스택 프레임 위치를 가리키고 데이터 액세스를 위한 참조 지점을 제공

 

 

지역변수는 스택에, new를 통해 동적할당 된 값은 heap에 들어가게 된다.
(따라서 함수가 반환되어도 heap에 할당된 데이터는 해제되지 않는다.)


func1 호출

func1 호출

func1를 호출하게 되면 먼저 main 함수의 return address와 frame를 순서대로 스택에 push한다.

그 이후에 func1를 로드하고, func1의 지역 변수 등을 스택에 담는다.

 

return address: 함수 호출 후 이전 함수에서의 코드(text) 위치를 기억하는 포인터


func1 반환 (함수 종료)

func1 return

func1 함수가 return 되어 종료되었을 때, func1에 사용되었던 지역변수 및 인자등을 가지고 있던 스택영역이 해제되면서 반납되게 된다. (이전 frame pointer가 기준)


main으로 되돌아가기

back to main

func1함수가 할당되어 있던 스택영역이 반납이 된 후에, frame pointer가 스택에서 pop이 된다.

(main함수와 func1 함수를 구분하고 있던 포인터를 pop한 것이라고 생각해도 된다.)

 

이후 stack pointer는 return address를 가리키게 된다.

back to main 2

return address가 가리키는 것은 func1를 호출 전의 코드를 가리킨다. 따라서 stack pointer가 현재 가리키고 있는 return address가 가리키고 있는 코드가 다음 실행할 코드가 되고 return address 또한 pop 된다.

 

이렇게 되면 func1함수를 호출한 코드까지 다시 되돌아 오고 나머지 코드가 다시 실행 될 수 있다.


Stack Overflow

 

위 과정에서 함수 호출이 매우 많이 이어지면 stack의 용량이 넘쳐 스택 오버플로우 에러가 발생하게 된다.