자료구조를 배우다가 동적 메모리, 정적 메모리, 동적 프로그래밍, 정적 프로그래밍 등등의 동/정적 단어를 많이 접할 수 있다. 영어로 풀어 쓰면 좀 더 이해하기 쉽다. 진짜
- 정적 메모리 할당 (Static Memory Allocation)
- 동적 메모리 할당 (Dynamic Memory Allocation)
정적은 정해진 크기, 동적은 알고리즘에 따라서 다른 메모리를 할당하는 것이다ㅎㅎ
조금 더 세부적으로 배워보자.
정적 메모리 할당
- 프로그램 시작 전에 미리 정해진 크기의 메모리를 할당하는 것
- 처음에 결정된 크기보다 더 큰 입력이 들어오면 처리 못함
- 더 작은 입력이 들어온다면 남은 메모리 낭비
딱봐도 쉽지만 비효율적이라는 것이 느껴지지 않는가?
우리가 처리했던 대부분의 메모리는 이렇게 할당 되었다. 우리가 하는 일이 늘 그렇지 뭐...흑흑
int i, j;
int buffer [100];
char name[] = "data structure";
buffer가 심히 낭비되고 있는 모습
동적 메모리 할당
- 프로그램 실행 도중에 동적으로 메모리를 할당
- 컴파일 할 때 미리 안정해짐
- 사용이 끝나면 시스템에 메모리 반납
- 매우매우 효율적
- 소스코드가 복잡함(내가 고생함)
- 메모리를 다 사용한 다음에 반드시 해제시켜줘야함. 안한다면 메모리 누수 효과 발생
#include <stdlib.h> //동적 메모리 관련 함수 불러오기
...
int *ptr = NULL;
int size = 100;
ptr = (int*) malloc (sizeof(int)*size); // malloc() 메모리 할당
...
free ( ptr ); // 메모리 해제
ptr주소 값이 int의 사이즈에 의해 메모리 크기가 결정됨을 볼 수 있다.
malloc() 함수
stdlib.h 헤더 안에 있는 함수다.
malloc함수는 바이트 단위로 메모리를 할당한다.
메모리 블럭의 첫 번째 바이트에 대한 주소를 반환하는데, 요청 값이 없으면 NULL을 반환한다.
int형 데이터 저장을 위한 메모리 공간을 위해서는
int *p;
p = (int*) malloc (sizeof(int));
이런식으로 p의 크기를 결정해주면되고
char형 데이터 저장을 위한 메모리 공간을 위해선
char *p;
p = (char*) malloc( sizeof(char));
이런식으로 주소의 메모리를 설정해준다.
다시 말하지면 malloc은 다음과 같은 형식을 띈다.
void *malloc(size_t size);
free() 함수
void free(void *ptr);
위와 같은 형태로 ptr에 할당되었던 메모리 블록을 시스템에 반납한다.
반납할때는 value를 써줘야하기 때문에 *를 붙인다.
실제로는 다음과 같이 사용된다!
int *p;
p = (int*) malloc(sizeof(int));
free(p);
포인터를 이용한 메모리 할당
이렇듯 동적 메모리 할당은 '포인터'로 이루어진다.
포인터가 값이 할당된 주소를 가리키니 포인터를 활용하는 것은 당연지사!!
동적 메모리가 사용되고 다시 반납되는 과정을 보도록 하자.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *pi = NULL; char *pc = NULL;
pi = (int *) malloc ( sizeof(int) ); // 동적 메모리 할당
if ( pi == NULL ) { printf("동적 메모리 할당 오류\n"); exit(1); }
*pi = 100; // 동적 메모리 사용
printf("%d\n", *pi);
free(pi); // 동적 메모리 반납
pc = (char *) malloc ( sizeof(char) ); // 동적 메모리 할당
if ( pc == NULL ) { printf("동적 메모리 할당 오류\n" ); exit(1); }
*pc = 'm'; // 동적 메모리 사용
printf("%c\n", *pc);
free(pc); // 동적 메모리 반납
return 0;
}
실제 값을 지정하지 않고 *pi, *pc만을 가정한다. malloc함수로 동적 메모리를 할당하고 실제로 사용한다.
그리고 마지막으로 free함수로 동적 메모리를 반납한다!!
포인터로 배열을 지목하는 방법도 어렵지 않다.
#include <stdio.h>
#include <malloc.h>
int main(void) {
int i, size=5;
int *arr;
arr = (int*) malloc ( sizeof(int) * size );
for ( i=0; i<size; i++ ) {
arr[i] = i;
}
for ( i=0; i<size; i++ ) {
printf("%d\n", *(arr+i));
}
free (arr);
return 0;
}
여기선 arr또한 int로 받아 동적 메모리를 할당하고 arr안에 int형 숫자 i를 차례대로 넣어준다.
그리고 다시 i를 출력하는데 이 때 포인터로 값을 참조했다. 이후 arr의 메모리들을 해방!! 시켜준다.
그 외의 동적 메모리 함수들
calloc()
void *calloc(size_t n, size_t size);
0으로 초기화된 메모리를 할당하는 함수다.
malloc은 어떠한 값의 메모리가 들어갈지 지정해줘야하지만 calloc은 무조건 int형 0만 쏙쏙 집어 넣는다.
realloc()
void *realloc(void *memblock, size_t size);
할당하였던 메모리 블록의 크기를 변경하는 것이다. malloc에서 지정해줬던 사이즈를 다시 키우거나 줄이는 작업이 필요할 때 쓴다.
int *p;
p = (int*) malloc (5 * sizeof(int));
p = (int*) realloc (p, 7 * sizeof(int));
'Data Structure [C] > 문돌이도 할 수 있는 [C언어 자료구조]' 카테고리의 다른 글
#19 [C 자료구조] 스택: 자료 더미 (0) | 2019.04.22 |
---|---|
#18 [C 자료구조] 자기 참조 구조체: 나야나 (0) | 2019.04.21 |
#16 [C 자료구조] 열거형(enum)과 공용체(union) (0) | 2019.04.20 |
#15 [C 자료구조] 포인터와 구조체 (0) | 2019.04.20 |
#14 [C 자료구조] 구조체: 다른 타입들의 배열 (0) | 2019.04.20 |