C언어에서 메모리 할당을 위한 방법으로 크게 정적할당과 동적할당이 있습니다.
정적할당(Static memory allocation)
프로그램이 실행되기전에 크기가 결정
정적할당은 이미 명시적으로 메모리를 얼마나 할당할지 정해주고 가는 것입니다.
1
2
3
int i;
double d;
char c;
이렇게 C언어에서 변수를 생성할때 자료형을 지정을 해줍니다. int는 4바이트, double 8바이트 char 1바이트가 생성이 됩니다. 프로그램이 실행하기도 전에 총 몇바이트의 메모리가 필요한지 공간크기를 미리 알려줍니다.
동적할당(Dynamic memory allocation)
하지만 정적할당에는 한가지 단점이 있습니다. 정확하게 필요한 메모리양이 적절한지 모를 수 있습니다. 만약 필요한 것보다 적게 할당한다면 메모리 부족으로 프로그램이 정상적으로 작동하지 못할 것이고 필요한 공간보다 너무 많이 할당하면 자원을 불필요하게 많이 잡아먹는 것 역시 좋지 않습니다.
필요한 만큼 할당할 수 없을까? 또 다른 표현으로 프로그램이 실행되는 도중에 동적으로 할당하는 것을 의미합니다. 프로그램이 실행후/실행 도중에 메모리 공간이 결정됩니다.
여기서 코딩테스트를 준비해보셨다면 동적이라는 의미가 여기서도 동일합니다. 미리 지정해주는 것이 아닌 코드가 돌아가는 동안 동적으로 결정된다는 의미입니다.
메모리 할당과 해제 (malloc, free)
1
void* malloc(size_t size)
동적할당을 하기 위해서는 조금 복잡한 코드가 필요합니다.
size 바이트 만큼 메모리 공간을 할당하여 이 공간의 시작 주소를 void* 형으로 리턴합니다.
만약 size바이트 만큼 메모리 공간을 할당할 수 없으면 NULL(0)을 리턴하게 됩니다.
1
void free(void *p)
인수로 주어진 포인터 p가 가리키는 공간을 해제
이렇게 자유 저장공간을 사용하는 이유를 다시 정리하자면 필요한 메모리 공간이 동적으로 결정되는 상황에 대처하기 위해 또는 공간을 아껴쓰기 위함입니다. C언어가 개발되던 70년대의 컴퓨터 성능을 생각하면 1바이트라도 아껴써야 했습니다. 하지만 이런 특성은 메모리 직접 제어라는 강력한 무기가 되었고 다른 언어보다 빠르다는 특징이 있습니다. 물론 메모리 직접제어가 보안에 취약하다던가 위험한 면도 있습니다.
그리고 동적으로 변화하는 리스트, 스택, 큐, 데크등의 자료구조를 구현하기 위해서 사용합니다.
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>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
int main() {
int* p;
int n, i;
printf("입력하고자하는 정수를 입력 : ");
scanf("%d", &n);
p = (int*)malloc(n * sizeof(int));
printf("%d개의 정수를 입력해주세요 : ",n);
for (i = 0; i < n; ++i)
scanf("%d",&p[i]);
printf("입력한 정수를 역수로 출력합니다 : ");
for (i = n-1; i >= 0 ; --i)
printf("%d ", p[i]);
printf("\n");
free(p);
return 0;
}
배열 p를 미리 지정해주는 것이 아니라 정수 n을 받고 sizeof(int)즉 4바이트 n개 만큼의 크기를 p에다가 할당을 합니다.
여기서 malloc는 정해진 자료형 공간의 시작 주소를 리턴하게 됩니다. 즉 p는 p라는 배열의 시작주소를 리턴받게 됩니다.
1
2
p = (int *)malloc(n*sizeof(int));
assert(p!=NULL);
여기서 assert를 사용하면 디버깅할때 특정 조건을 검사하기 위한 매크로를 작성할 수 있습니다.
assert(수식); 형태로 사용합니다. 프로그램 수행중 수식이 거짓이면 오류메세지를 출력하고, 프로그램을 종료합니다.
Comments powered by Disqus.