25. 메모리 관리와 동적 할당
I. C 언어의 메모리 구조
-
스택(Stack), 힙(Heap)그리고 데이터(Data) 영역
-
메모리 공간은 스택, 힙, 데이터영역으로 나뉘어 진다.
- 할당 시기 : 프로그램이 실행될 때마다
- 할당 장소 : 메인메모리인 RAM
- 할당 용도 : 프로그램 실행 시 필요한 메모리 공간의 할당을 위해
-
데이터 영역(Data Area)
- 전역 변수와 static 변수가 할당되는 영역이다. 이 영역에 할당되는 변수들은 일반적으로 프로그래의 시작과 동시에 할당되고, 프고르매이 종료되어야만 메모리에서 소멸된다.
-
스택 영역(Stack Area)
- 지역변수와 매개 변수가 저장되는 영역. 이 영역에 할당된 변수는 함수 호출이 완료되면 사라진다는 특징이 있다.
-
힙 영역(Heap Area)
- 프로그래머가 관리하는 메모리 영역이다. 필요에 의해서 메모리 공간이 할당 및 소멸되는 영역이다.
-
- 프로그램의 실행과 메모리의 흐름
- #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 보다는 전역변수가 먼저 데이터 영역에 올라가는 것이 먼저다.
- 두번째 : main 함수의 호출
-
- 지역 변수인 m이 선언과 동시에 123으로 초기화 되었다.
- 지역변수 m은 main 함수 내에서 선언된 지역 변수이므로 main함수가 완료 되기 전까지만 유효할 것이다.
- 세번째 : fct1 함수의 호출
-
- fct1 함수 호출되면서 인자 m을 전달한다. 전달된 m은 fct1의 매개변수인 c가 선언되면서 123으로 초기화 된다.
- fct1 함수내에 있는 지역변수 d도 선언되면서 30으로 초기화 된다.
- 네번째 : fct1함수의 완료 그리고 fct2 함수의 호출
-
- fct1 함수가 완료 되면 fct2가 호출되고 있는데 fct1의 스택공간은 지워져 버리고 fct2의 스택 공간이 할당된다.
- 다섯째 : fct2 함수의 완료, main 함수의 완료 그리고 프로그램의 완료
-
- 먼저 fct2가 완료 되면 스택공간에서 지워지고 그다음 메인이 끝나기 때문에 메인부분이 사라진다. 그리고 전역변수로 선언된 것이 지워지면서 프로그램은 종료된다.
-
배열은 반드시 상수로 선언해야 하는 이유
- 배열 선언은 반드시 상수를 사용한다.
- #include <stdio.h>
- void function(int);
- int main()
{
int m = 0;
scanf("%d",&m);
function(m); - return 0;
} - void function(int i)
{
int array[i];
}
-
위의 소스가 관연 될까?
- 당연히 안된다. 배열을 선언 할때 변수를 쓰면 안된다.
-
배열 선언 시 반드시 상수만 써야 하는 이유
- 스택과 데이터 영역에 할당될 메모리의 크기는 컴파일되는 동안에 결정되어야 한다.
- void function(int a)
- {
- int b;
- int c[2];
- }
-
위의 소스는 메모리에 얼마나 할당을 받아야 할까?
- 4(int) + 8(int * 2) 총 12바이트를 받으면 된다.
- void function()
- {
- int i = 10;
- int array[i];
- }
-
위의 소스는 메모리에 얼마나 할당을 받아야 할까?
- 4 + 40 = 44바이트를 받으면 된다.
-
하지만 컴파일러는 4 + 4 = 8바이트를 받게 된다.
- 이유는 int i = 10을 보고 int 형이구나 구만 생각을 한다 그래서 초기화에 대한건 생각을 안한다.
II. 메모리 동적 할당
-
malloc 함수 & free 함수
-
malloc 함수
- #include<stdilb.h> void* malloc(size_t size) : 함수 원형이며 할당하고자 하는 메모리의 크기를 함수 호출 시 바이트 단위로 전달하면 그 크기만큼 메모리를 힙에 할당하게 된다.
-
free 함수
- #include<stdlib.h> void free(void* ptr) : 해제하고자 하는 메모리 공간을 가리키는 포인터를 인자로 전달하면, 해당 포인터가 가리키는 메모리 공간을 해제한다.
-
- #include <stdio.h>
#include <stdlib.h> - int main()
{
int* a;
a = (int*)malloc(sizeof(int)); - if(a==NULL)
{
puts("메모리 할당에 실패");
exit(1);
}
*a = 20;
printf("힙에 저장된 변수 a : %d\n",*a); - free(a);
return 0;
}
- 위와 같이 사용을 한다.
- #include <stdio.h>
#include <stdlib.h> - void function(int);
- int main()
{
int m =0;
fputs("배열의 크기를 입력하세요 : ",stdout);
scanf("%d",&m);
function(m);
return 0;
} - void function(int i)
{
int* array = (int*)malloc(sizeof(int)*i);
int j;
if (array == NULL)
{
puts("메모리 할당에 실패");
exit(1);
} - for(j=0;j<i;j++)
array[j] = j+1;
for(j=0;j<i;j++)
printf("%d",array[j]);
printf("\n");
free(array);
}
- 위의 소스는 앞전에 변수를 받아서 사용자가 배열의 크기를 결정짓게 하겠다는 소스이다.
-
calloc 함수
-
#include<stdlib.h> void *calloc(size_t elt_count, size_t elt_size) : 함수 원형이며
- malloc과 같은 역할을 한다. 다만 calloc은 할당받으면서 초기화를 해준다고 한다.
-
이 글은 스프링노트에서 작성되었습니다.
'2. C/C++ > 01. C' 카테고리의 다른 글
26. 매크로와 전처리기 (0) | 2008.12.07 |
---|---|
24. 파일 입.출력 (0) | 2008.12.07 |
23. 구조체와 사용자 정의 자료형2 (0) | 2008.12.07 |
22. 구조체와 사용자 정의 자료형1 (0) | 2008.12.07 |
21. 문자와 문자열 처리 함수 (0) | 2008.12.07 |