Data&Stack&Heap?

Heap & Stack & Data?

프로그램을 실행시키면 OS는 우리가 실행시킨 프로그램을 위해 메모리 공간을 할당해준다. 할당되는 공간은 크게 Stack, Heap, Data 영역으로 나뉘어 진다. 각 공간은 할당되어지는 부분, 시간 등이 다르다.

Data

Data영역은 전역변수와 static변수가 할당되는 영역이다. 프로그램의 시작과 동시에 할당되고, 프로그램이 종료되어야 메모리에서 소멸된다.

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int a = 10;	// 데이터 영역에 할당
int b = 20;	// 데이터 영역에 할당

int main() {

	...

	return 0;
}

image

위와 같은 코드에서 int형 변수 a, b는 프로그램 실행시, main 함수가 호출되기 전에 데이터 영역에 할당된다. 그렇기 때문에 프로그램이 종료될 때까지 메모리상에 존재한다. (전역변수가 프로그램이 종료될 때 까지 존재하는 이유)


Stack

Stack 영역은 함수 호출 시 생성되는 지역 변수와 매개 변수가 저장되는 영역이다. 함수 호출이 완료되면 사라진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>

void fct1(int);
void fct2(int);

int a = 10;	// 데이터 영역에 할당
int b = 20;	// 데이터 영역에 할당

int main() {

	int i = 100;	// 지역변수 i가 스택 영역에 할당

	fct1(i);
	fct2(i);

	return 0;
}

void fct1(int c) {
	int d = 30;	// 매개변수 c와 지역변수 d가 스택영역에 할당
}

void fct2(int e) {
	int f = 40;	// 매개변수 e와 지역변수 f가 스택영역에 할당
}

image

a, b를 Data 영역에 할당한 뒤에 main함수를 호출하면서 int형 변수 i는 지역변수로서 Stack 영역에 할당된다. 그 뒤에 fct1()이라는 함수를 호출하면서 fct1함수의 매개변수인 c와 d가 Stack 영역에 할당된다. fct1()이라는 함수호출이 끝나면 c와 d는 스택영역에서 삭제되며, 그 뒤 fct2()라는 함수를 호출하면서 매개변수 e와 지역변수 f가 Stack 영역에 할당된다.


Heap

필요에 의해 동적으로 메모리를 할당 할 때 사용한다. Heap 영역을 설명하기 전에 아래의 코드를 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
12
int main() {

	// 정상적인 배열선언
	int arr[10];

	// 비 정상적인 배열선언
	int i = 0;
	scanf("%d", &i);
	int arr[i];

	return 0;
}

위의 코드에서 두 번째 배열선언이 왜 비 정상적인 배열선언일까? 그 이유는 바로 할당될 메모리의 크기를 알 수 없기 때문이다. Stack 영역에 할당될 메모리의 크기는 컴파일 타임에 결정된다고 되어있다. 정상적인 배열 선언의 경우 arr이라는 배열의 크기가 40바이트 라는것을 알 수 있다. 하지만 비 정상적인 배열선언의 경우 i의 크기가 4바이트 라는 것을 알 수 는 있으나, arr이라는 배열의 크기는 알 수 없다. 또 다른 경우를 보자


1
2
3
4
5
6
7
int main() {

	int i = 10;
	int arr[i];

	return 0;
}

위의 경우에서는 배열의 크기를 알고 메모리를 미리 할당할 수 있을까? 정답은 아니다. 컴파일을 하는 동안 i가 4바이트의 크기라는 것을 알 수는 있으나, 그 값이 10으로 초기화 되었다는 사실은 무시하고 넘어간다. 값이 10으로 초기화 되었다는 사실은 실행되는 동안, 즉 런타임에 결정된다. 그렇기 때문에 컴파일러는 arr의 크기가 40바이트가 된다는 사실을 알 수 없다.


사용자의 요구에 맞게 메모리를 할당(런타임)해 주기 위해서는 메모리 동적 할당을 통해 힙 영역에 메모리를 할당해야 한다.