이번에는 프로세스와 프로그램이 실행될 때 구성되는 메모리 공간, 그리고 스택의 사용 범위에 대해서 알아보겠습니다.
먼저 프로세스란 실행 중에 있는 프로그램을 의미합니다. 만약 johee.exe라는 게임 실행파일이 있을 때 이것을 프로그램이라고 부릅니다. 게임을 하기 위해 johee.exe의 실행파일을 실행시키면 프로그램의 실행을 위해 메모리 할당이 이뤄지고, 이 메모리 공간으로 바이너리 코드가 올라가게 됩니다.
이 순간부터 프로그램은 프로세스라고 불리게 됩니다.
프로그램이 실행될 때 구성되는 메모리 공간에 대해서 이야기하면,
기본적으로 전역변수나 static 변수의 할당을 위해 존재하는 Data영역,
지역변수 할당과 함수 호출시 전달되는 인자값들의 저장을 위해 존재하는 Stack영역,
그리고 동적 할당(new, malloc,
calloc)을 위해 존재하는 Heap영역으로 구성됩니다.
프로그램을 실행시키면, 실행파일 내에 존재하는 명령어들이 메모리상에 올리가서 순차적으로 실행됩니다. 이렇게 실행파일을 구성하는 명령어들이 올라가는 메모리영역을 가리켜 Code영역이라 합니다.
위에서 설명한 메모리 공간들을 하나로 묶으면, 프로그램 실행 시 만들어지는 메모리 공간의 구성을 위의 그림처럼 짐작할 수 있습니다.
위 그림은 프로세스 생성 시 만들어지는 메모리 구조를 보여주고 있으며, 이 자체를 그냥 프로세스라고 표현하기도 합니다. 그 이유는 프로그램 실행을 위해서 명령어들이 메모리 공간에 올라와 있는 상태이고, 프로그램 실행을 위해서 필요한 메모리 공간이 할당되어 있는 상태이기 때문입니다.
만약 MS_WORD, 멜론 플레이, johee.exe 이렇게 세 개의 프로그램을 실행시킨다면, 위 그림과 같은 메모리 구조로 총 세개가 구성됩니다. 그림과 같은 메모리 구조는 실행되고 있는 프로세스 개수만큼 생성된답니다.
보통 힙과 스택은 예약된 공간으로 비어있는 상태입니다. 이는 미사용 공간으로 처음부터 힙과 스택이 할당되어 있는게 아니라는 의미입니다. 프로그램이 실행이 되면 스택의 경우
함수가 호출될 시, 힙의 경우는 개발자가 동적으로 할당했을 시에 메모리 공간이 채워지게 됩니다.
그럼 현재 프로그램에서 스택이나 힙을 최대 얼마까지 할당할 수 있는지 보겠습니다.
비쥬얼 스튜디오는 윈도우 환경에 맞춰 기본 스택 예약 크기를 1MB로 지정합니다. 하지만 기본으로 예약된 크기 말고도, 기본적으로 힙과 스택은 사용자 지정에 의해 최대 크기를 정할 수 있습니다. 그렇다고해서 무한한 공간은 아니며, 스택과 힙은 윈도우(운영체제나 컴퓨터 사양에 따라 다르겠지만 윈도우 기준에서)에서 설정한 램 메모리만큼 최대로 할당할 수 있다고 합니다.
최대 크기 지정은 프로젝트 속성 > 링커 > 시스템에 '힙 예약 크기'와 '스택 예약 크기'에 예약할 크기를 지정해주어서 힙과 스택의 사용할 크기를 예약할 수 있습니다.
그럼 스택 예약 크기가 기본값 1MB로 되어있는 상태에서 대략 2MB를 사용하는 배열을 선언하여 실행해보겠습니다.
1KB 는 1024Byte이고
1MB는
1,048,576Byte입니다.
1
2
3
4
5
6
|
int main()
{
char test[2000000];
return 0;
}
| cs |
실행을 하면 위 사진처럼 Stack overflow가 발생했다고 나옵니다.
그럼 스택 예약 크기를 조금 더 늘려본 후 실행해보겠습니다.
스택 예약 크기를 대략 3MB로 지정해주었습니다.
(스택 예약 크기는 바이트 크기로 입력을 받습니다. )
다시 프로그램을 실행을 하면 스택 예약 크기를 대략 3MB로 늘린 결과 맨 처음 기본값 1MB에서 스택오버플로우가 발생했던 코드가 정상적으로 실행이 되었습니다.
이처럼 스택 포인터가 스택의 경계를 넘어설 때 스택 오버플로우가 발생합니다. 호출 스택은 제안된 양의 주소 공간을 이루며 대개 프로그램 시작 시 결정됩니다. 프로그램이 호출 스택에서 이용 가능한 공간
이상을 사용하려고 시도할 때, 스택이 오버플로된다고 하며 이 경우 일반적으로 프로그램 충돌이 발생하게 됩니다. 스택 오버플로의 가장 흔한 원인은 상당히 깊거나 무한으로 이어지는 루프나 매우 큰 크기의 배열 할당입니다.