C 프로그램에서 사용하는 메모리 구조에 대해 설명하고 있다.
우리가 아주 잘 알고 있는 hello world 프로그램이 있다고 하자! 보는 사람에 따라서, 단순히 모니터에 hello world 를 출력한다고만 생각할 수도 있고, 메모리의 구조를 들어가며, 설명을 할 수도 있을 것이다. 또한 하드웨어적으로 어셈블러를 이용해서도 설명할 수 있을 것이다.
이렇듯, 겉으로 보면 아주 단순한 작업들도 막상 속을 들여다보면 아주 복잡한 작업들이 수행되는 것을 알 수 있다.
이 문서에서 다룰 C 언어에서 사용하는 메모리의 스택, 힙, 데이터영역 역시 마찬가지이다. 이 세가지에 대해서 잘 모른다고 해도, 프로그래밍을 하는데는 큰 문제가 안된다. 하지만, 원리를 아는 것과 모르는 것과는 많은 차이가 있다.

데이터 영역(Data Area)

전역 변수와 static 변수가 할당되는 영역이다. 이 영역에 할당되는 변수들은 일반적으로 프로그램의 시작과 동시에 할당되고, 프로그램이 종료되어야만 메모리에 해제된다. 즉, 데이터 영역에 할당된 변수는 프로그램이 종료될 때까지 계속 존재한다는 특징을 지닌다.

스택 영역(Stack Area)

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

void stack(int a)
{
int b=10;
}

인자가 전달되면서 stack 라는 함수가 호출되면, 일단 매개 변수 a 가 스택영역에 올라가게 된다. 그리고 나서 지역변수 b 가 스택영역에 올라갈 것이다. 반대로 stack 함수의 호출이 완료되고 나면, 변수 a 와 변수 b 는 스택영역에서 사라져 버린다. 스택 영역은 가장 밑에서 부터 위쪽 방향으로 증가한다.

힙 영역(Heap Area)

프로그래머가 관리하는 메모리 영역이다. 즉 프로그래머의 필요에 의해서 메모리 공간이 할당 및 소멸되는 영역이다. 힙 영역은 데이터 영역의 아래에서 부터 아래 방향으로 증가한다.

정적 할당(Static Allocation)

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

{
...
int m=0;
scanf("%d", &m);
void function(m);
return 0;
}
void function(int i)
{
int array[i];     // 입력받은 길이 만큼 스택에 배열 할당
}

위에 프로그램은 컴파일 에러를 발생시킨다. 이유는 배열의 갯수를 변수로 선언했기 때문이다.
컴파일러가 프로그램을 컴파일하면서, array 배열이 몇 바이트의 공간을 필요로 하는지 알 수 없기 때문이다. 그렇다면, 아래의 코드를 보자!

int b;
int a[2];

총 12 바이트의 스택 공간이 할당되어야 함을 알 수 있다. 이렇듯, 스택 공간에 할당될 메모리의 크기는 컴파일러에 의해서 알 수 있어야 한다.

동적 할당(Dynamic Allocation)

힙 영역에 할당될 메모리 크기는 실행되는 동안에 결정된다.
동적 할당에 대표적인 함수로는 malloc() 와 free() 이다.

{
...
int* a;
a=(int*)malloc(sizeof(int));    // int 형 데이터 저장을 위해 형변환
if(a==NULL)
{
puts("fail!!");
exit(1);
}
*a=20;
printf("hip variable a: %d \n", *a);
 
free(a);
return 0;
}

malloc 함수는 인자의 숫자에 따라 힙에 메모리를 할당한다. 스택에서 배열을 할당했을 때와 비교해보면, 변수를 사용한 것이 차이점이라고 할 수 있겠다. 성공적으로 메모리 할당이 이루어지면, 할당된 메모리의 첫번째 주소를 리턴한다. 실패 시에는 NULL 포인터를 리턴한다.
또한 malloc 함수는 리턴형이 void* 이기 때문에, 용도에 맞게 형 변환을 해야 한다. 예를 들어서 int 형 데이터를 저장하기 위해서 메모리를 할당했다면, 리턴되는 void* 를 int* 로 변환해야 한다.
free 함수는 힙에 할당된 메모리를 해제한다. 해제하고자 하는 메모리 공간을 가리키는 포인터를 인자로 전달하면, 해당 포인터가 가리키는 메모리 공간은 해제된다. 매개 변수의 타입으로 void* 로 선언되어 있다. 따라서 어떠한 포인터도 인자로 전달될 수 있다.

  • computer/programming/c_언어의_메모리_구조.txt
  • Last modified: 3 years ago
  • by likewind