스택 프레임 && 메모리의 동적 할당

jeongpar·2021년 2월 10일
0

interview_answer

목록 보기
2/9

스택 프레임(stack frame)

메모리의 스택 영역은 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역이다.
스택 영역은 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸한다.

함수가 호출되면 스택에는 함수의 매개변수, 호출이 끝난 뒤 돌아갈 반환 주소값, 함수에서 선언된 지역 변수 등이 저장된다.
이렇게 스택 영역에 차례대로 저장되는 함수의 호출 정보를 스택 프레임(stack frame)이라고 한다.

스택 프레임의 동작 방식

int main(void)
{
	func1();
    	return (0);
}

void func1()
{
	func2();
}

void func2()
{
}

다음 그림은 위 예제 코드에서 함수 호출에 의한 스택 프레임의 변화를 보여주고 있다.

  1. 프로그램이 실행되면, 가장 먼저 main() 함수가 호출되어 main() 함수의 스택 프레임이 스택에 저장된다.
  2. func1() 함수를 호출하면 해당 함수의 매개변수, 반환 주소값, 지역 변수 등의 스택 프레임이 스택에 저장된다.
  3. func2() 함수를 호출하면 해당 함수의 스택 프레임이 추가로 스택에 저장된다.
  4. func2() 함수의 모든 작업이 완료되어 반환되면, func2() 함수의 스택 프레임만이 스택에서 제거된다.
  5. func1() 함수의 호출이 종료되면, func1() 함수의 스택 프레임이 스택에서 제거된다.
  6. main() 함수의 모든 작업이 완료되면, main()함수의 스택 프레임이 스택에서 제거되면서 프로그램이 종료된다.

이처럼 스택은 가장 나중에 저장된 데이터가 가장 먼저 인출되는 방식으로 동작한다.
이러한 방식을 후입선출(LIFO, Last-In First-Out) 방식이라고 한다.
이때 스택은 push 동작으로 데이터를 저장하고, pop방식으로 데이터를 인출한다.

스택 오버플로(stack overflow)

함수의 호출이 너무 많아지면, 해당 프로그램은 스택 오버플로에 의해 종료된다.

만약 재귀 호출이 무한히 반복되면, 위 그림에서 3단계 이후로는 재귀 호출에 의한 스택 프레임이 계속해서 쌓여만 간다.
이렇게 스택의 모든 공간을 다 차지하고 난 후 더 이상의 여유 공간이 없을 때 또 다시 스택 프레임을 저장하게 되면, 해당 데이터는 스택 영역을 넘어가서 저장되게 된다.

이렇게 해당 스택 영역을 넘어가도 데이터가 저장될 수 있으면, 해당 프로그램은 오동작을 하게 되거나 보안상의 크나큰 취약점을 가지게 된다. C언어에서는 실행 중인 프로그램에서 스택 오버플로가 발생하면, 에러를 발생하고 곧바로 강제 종료시킨다.

메모리의 구조

프로그램이 실행되기 위해서는 먼저 프로그램이 메모리에 로드되어야 한다.
또한, 프로그램에서 사용되는 변수들을 저장할 메모리도 필요하다.

따라서 컴퓨터의 운영체제는 프로그램의 실행을 위해 다양한 메모리 공간을 제공하고 있다.
프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간은다음과 같다.

  1. 코드(code)영역
  2. 데이터(data)영역
  3. 스택(stack)영역
  4. 힙(heap)영역

다음 그림은 운영체제가 제공하는 메모리 공간을 표현하고 있다.

  • 코드영역
    메모리의 코드 영역은 실행할 프로그램의 코드가 저장되는 영역으로 텍스트 영역이라고도 부른다.
    CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.

  • 데이터 영역
    메모리의 데이터 영역은 프로그램의 전역 변수와 정적 변수가 저장되는 영역이다.
    데이터 영역은 프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸한다.

  • 스택 영역
    메모리의 스택 영역은 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역이다.
    스택 영역은 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸한다.
    이렇게 스택 영역에 저장되는 함수의 호출 정보를 스택 프레임(Stack Frame)이라고 한다.
    스택 영역은 push 동작으로 데이터를 저장하고, pop 동작으로 데이터를 인출한다.
    이러한 스택은 후입선출(LIFO, Last-In First Out) 방식에 따라 동작하므로, 가장 늦게 저장된 데이터가 가장 먼저 인출된다.
    스택 영역은 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.

  • 힙 영역
    메모리의 힙 영역은 사용자가 직접 관리할 수 있고 관리해야 하는 메모리 영역이다.
    힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다.
    힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.

메모리의 동적 할당(dynamic allocation)

데이터 영역과 스택 영역에 할당되는 메모리의 크기는 컴파일 타임(compile time)에 결정된다.
하지만 힙 영역의 크기는 프로그램이 실행되는 도중인 런 타임(run time)에 사용자가 직접 결정하게 된다.
이렇게 런 타임에 메모리를 할당하는 것을 메모리의 동적 할당(dynamic allocation)이라고 한다.

메모리 누수(memory leak)

사용이 끝난 메모리를 해제하지 않아서 메모리가 부족해지는 현상
따라서 다 사용한 메모리는 해제해 주어야 한다.

출처

  • http://www.tcpschool.com/c/c_memory_stackframe
  • http://www.tcpschool.com/c/c_memory_structure
profile
정팔입니다.

0개의 댓글