C언어의 메모리 구조

2014. 1. 20. 21:33Programing/C Language

1. 스택, 힙, 데이터 영역

 

프로그램을 실행시키기 위해서는 메모리 공간이 필요하다. 그래서 컴퓨터는 프로그램의 실행을 위해 메모리 공간을 할당해 준다. 이렇게 해서 할당디는 메모리 공간은 크게 스택, 힙 , 데이터 영역으로 나뉜다.

 

할당 시기 : 프로그램이 실행될 때마다

할당 장소 : 메인 메모리에 할당되는데 메인메모리는 RAM이다

할당 용도 : 프로그램 실행 시 필요한 메모리 공간의 할당을 위해서

 

------------------------------------------------------------|

전역변수          |        프로그래머 할당        |  지역변수,매개변수|

static 변수     |                                  |                              |

------------------------------------------------------------|

데이터영역           힙 영역 ->                         <-      스택 영역

 

데이터영역

 

데이터 영여은 전역 변수와 static 변수가 할당되는 영역이다. 이 영역에 할당되는 변수들은 일반적으로 프로그램의 시작과 동시에 할당되고 프로그램이 종료되어야만 메모리에서 소멸된다.

 

스택영역

 

스택영역은 함수 호출 시 생성되는 지역 변수와 매개 변수가 저장되는 영역이다. 이 영역에 할당된 변수는 함수 호출이 완료되면 사라진다는 특징을 지닌다.

 

힙 영역

 

힙은 프로그래머가 관리하는 메모리 영역이다. 즉 프로그래머의 필요에 의해서 메모리 공간이 할당 및 소멸되는 영역이다.

 


2. 프로그램의 실행과 메모리의 흐름

 

#include<stdio.h>

 

void fct1(int);

void fct2(int);

 

int a=10;

int b=20;

 

int main()

{

int m=123;

 

fct1(m);

fct2(m);

 

return 0;

}

 

void fct1(int c)

{

int d=30;

}

void fct2(int e)

{

int f=40;

}

 

첫 번째 프로그램의 시작 그리고 전역 변수의 저장

 

프로그램의 시작은 main 함수의 호출에서부터 이지만 실제로는 전역 변수가 데이터 영역에 올라가는 일이 main 함수의 호출보다 먼전 진행된다.

 

a 와 b가 전역변수로 선언되어 있으니 a와 b가 데이터 영역에 각각 10과 20으로 초기화되어 올라간다.

 

두 번째 main 함수의 호출

 

main 함수가 호출되고 지역 변수 m이 선언과 동시에 123으로 초기화된다. 이러면 스택에 m이 123으로 초기화되어 올라간다.

 

세 번째 fct1 함수의 호출

 

fct1 함수가 호출되면서 인자로 m을 전달하고 있다 따라서 fct1 함수의 매개변수 c는 123으로 초기화 되고 fct1 함수 내의 선언되어 있는 지역 변수 d도 30으로 초기화된다.

이 둘은 모두 fct1 함수 내에 선언된 지역 변수이므로 스택에 메모리를 할당하게 된다.

 

메모리 그림을 그려보면 main을 위한 스택 위로 fct1을 위한 스택공간을 형성하게 된다.

main 함수 호출이 완료된 상태가 아니고 main 함수가 실행중에 fct1 함수가 호출된 것이기 때문에 main을 위한 스택 공간은 아직 그대로 존재하고 있다.

 

네 번째 fct1함수의 완료 그리고 fct2 함수의 호출

 

fct2함수가 호출됬다는 의미는 fct1 함수의 호출이 완료되었다는 뜻이다. fct1의 스택공간은 지워져버리고 fct2의 스택 공간이 할당된다.

 

다섯 번째 fct2 함수의 완료, main함수의 완료 프로그램의 종료

 

fct2 함수가 완료되고 main함수를 종료한다 이러면서 스택이 비워지고 프로그램이 종료되면서 데이터영역도 비워진다.

(왠지 마음이 아프다 흑흑..)

 


3. 배열은 반드시 상수로 선언해야 하는 이유

 

배열 선언은 반드시 상수를 사용한다

 

#include<stdio.h>

 

void funtion(int);

 

int main()

{

int m=0;

scanf("%d",&m);

fuction(m);

 

return 0;

}

void fuction(int i)

{

int array[i];

}

 

위 소스의 문제점은 배열을 선언하는데 변수를 이용했다는 것이다. 반드시 상수만 써야한다.

 

배열 선언 시 반드시 상수만 써야 하는 이유

 

스택과 데이터 영역에 할당될 메모리의 크기는 컴파일되는 동안에 결정되어야 한다.

 

void function()

{

int i=10;

int array[i];

}

 

위의 함수는 44바이트의 크기가 할당된다는 것을 예상할 수 있다. 하지만 컴파일러는 i가 int 형 변수인 것만 알 뿐

얼마로 초기화 되어 있는지를 컴파일할 때 신경을 안쓴다. 그러므로 int array[i]라는 문장을 만나면 i가 얼마인지 모르기 때문에 메모리 공간의 크기를 알지 못한다.

 

(컴파일 되는 동안은 컴파일타임이라 하고 실행되는 시간을 런타임이라 한다 , i가 10으로 초기화 되는 시기는 컴파일타임이 아니고 런타임 이므로 저 위에 스태과 데이터 영역에 할당될 메모리의 크기는 컴파일되는 동안에 결정되어야 한다.

이 규칙에 안맞는다)

 

힙은 데이터 영역이난 스택과 달리 런-타임에 필요한 만큼 메모리를 할당하고 해제할 수 있다.

 

할당해야할 메모리의 크기를 런-타임에 결정해야 하는 경우, 유용하게 사용되는 메모리 공간이 힙이다