오늘은 메모리공간에 대해서 조금 자세히 들여다 볼겁니다.
1. 메모리 공간의 4영역
우리가 소스코드를 작성하고 빌드하여 프로그램을 실행하면 운영체제(OS)는 메모리공간 할당을 시작합니다. 그 메모리공간은 용도에따라 4가지 영역으로 나뉘어집니다. 코드 영역(code) / 데이터 영역(data) / 힙 영역(heap) / 스택 영역(stack)
1. 코드 영역
실행되는 프로그램 소스코드, 즉 명령어들이 2진코드(binary code)형태로 저장되는 메모리공간입니다. 여기에 저장된 명령어들이 한 문장씩 꺼내져서 실행이 됩니다. 그리고 상수도 여기에 저장이 됩니다.
2. 데이터 영역
프로그램 실행과 동시에 할당이 되어 프로그램이 종료될 때 까지 남아있어야 하는 전역변수(global variable)와 static변수가 할당됩니다.
3. 힙 영역
프로그래머가 직접 관리할 수 있는 메모리 영역입니다. 나머지 메모리공간의 영역들은 생성과 소멸이 컴파일러에 의해 결정이 된다면 이 메모리공간은 프로그래머가 직접 데이터를 할당시키고 소멸시킬 수 있습니다. 이를 프로그래머에 의한 동적할당이라고 합니다.
4. 스택 영역
지역변수나 함수의 전달인자와 같이 함수의 호출시에만 필요한 변수를 저장하는 메모리 공간입니다.
프로그램이 실행되면 가장 먼저 데이터영역의 메모리공간에 전역변수와 static 변수들이 초기화되어 저장됩니다. 그 이후 main함수를 실행하면서 코드영역에서 명령문들을 한 문장씩 꺼내어 실행을 합니다. 그리고 코드를 실행하면서 필요한 지역변수나 함수의 전달인자와 같은 정보가 스택영역에 할당되고 소멸되는 과정이 반복됩니다.
우리가 지금까지 배운 변수나 배열과 같은 데이터들은 데이터영역과 스택영역으로 충분히 해결이 가능했습니다. 하지만 문자열과 같은 메모리의 주소값을 다루는 상황에서 데이터영역과 스택영역으로 해결이 되지 않는 상황, 혹은 프로그래머가 메모리공간을 한 바이트 단위로 아껴서 사용하고 싶은 경우에 힙영역을 사용하게 됩니다.
2. 힙 영역
힙 영역을 다루는 방법을 보겠습니다.
#include <stdio.h>
#include <stdlib.h> //표준 라이브러리
int main(void)
{
void * ptr1 = malloc(4); //heap영역의 동적할당을 위한 malloc()함수
void * ptr2 = malloc(20);
printf("%#x\n", ptr1);
printf("%#x\n", ptr2);
free(ptr1); //heap영역에 할당되었던 메모리공간 소멸을 위한 free()함수
free(ptr2);
return 0;
}
실행결과
0xec2dc8
0xec2df8
계속하려면 아무 키나 누르십시오 . . .
malloc함수는 heap영역의 메모리공간을 프로그래머가 직접 할당하기 위해 호출하는 함수이며 할당된 메모리의 주소값을 반환(return)합니다. malloc함수는 stdlib 헤더파일이라는 외부 라이브러리에 저장되어 있습니다. 따라서 #include
malloc함수를 사용하여 heap영역에 메모리공간을 할당하는 방법은 아래 그림과같이 정리가 됩니다.
malloc 함수 : heap영역에 우리가 지정한 크기의 메모리공간을 할당함과 동시에 그 주소값을 반환시켜 줍니다.
free함수 : 전달인자로 넣어준 포인터변수가 가르키는 메모리공간을 찾아가 할당을 해제합니다.
사실 free함수를 사용하지 않아도 프로그램이 종료되면서 heap영역에 할당된 메모리공간은 모두 소멸됩니다. 하지만 프로그램이 종료되기 전까지는 메모리공간을 낭비하므로 굳이 heap 영역을 쓴 이유가 무색해집니다. 따라서 heap영역에 할당한 메모리공간의 데이터가 더 이상 필요없어지면 free함수로 메모리공간을 비워주는 것을 습관화 하는것이 좋습니다.
malloc 함수와 비슷한 calloc, realloc 함수라는 것도 있습니다.
calloc(3,4); 는 총 3개의 블록을 각각 4byte크기로 heap영역에 할당해줍니다.
ptr = (int *)realloc(ptr, sizeof(int)*6); 은 malloc함수로 할당한 포인터 ptr이 가르키는 메모리공간의 크기를 24byte로 변경합니다.
'프로그래밍 언어 > C' 카테고리의 다른 글
(C언어) 34 - 문자 입출력 함수들 (0) | 2020.05.14 |
---|---|
(C언어) 33 - 스트림 (0) | 2020.05.14 |
(C언어) 31 - 함수 포인터 (0) | 2020.05.14 |
(C언어) 30 - 2차원 배열과 포인터 (0) | 2020.05.14 |
(C언어) 29 - 더블 포인터 (0) | 2020.05.14 |