메모리를 동적으로 할당 받는 이유는 일반 변수는 컴파일 단계에서 변수의 크기가 정해지기 때문에 프로그램이 실행 되면서 얼마만큼의 배열크기를 사용하게 될지 정확히 알 수 없기 때문에 넉넉하게 할당 받는다. 그래서 프로그램이 실행도중에 사용자가 원하는 만큼 메모리를 할당 받을 수 있다면 메모리 낭비가 줄어들고 프로그램도 안정적으로 동작이 된다. 그래서 나온 개념이 메모리 동적 할당이다.
C언어에는 Heap 영역에 사용자가 원하는 크기만큼 메모리를 할당받아 사용할 수 있다.
그것을 지원하는 3가지 함수가 있는데 malloc, calloc, realloc 이다. 이 포스팅에서는 이 3가지 함수에 차이점에 대해서 배워보도록 하자. 기본적으로 malloc 을 많이 사용하지만 다른 함수들도 알아 두면 유용할때가 많다.
그리고 참고로 메모리를 해제하는 함수는 free이다. 메모리를 할당하고 해제하지 않으면 나중에 사용할 heap 영역에 크기가 부족해 프로그램이 정상동작하지 않을 수 있다.
우선 malloc과 free에 기본적인 사용방법은 아래 링크를 참고하자. 정확히 이해하지 않으면 이번 포스팅이 어려울 수 있다.
C/C++ malloc, free를 사용한 메모리 할당 및 해제 : http://hijuworld.tistory.com/59
그리고 메모리 할당과 해제를 하는 원리는 아래 링크를 참고하자.
C, C++ 에서 동적 메모리의 할당과 해제 원리 : http://hijuworld.tistory.com/28
malloc과 calloc의 차이에 대해서 알아보자.
1. 할당받을 메모리 사이즈를 받는 파라미터의 갯수가 다르다.
2. calloc은 메모리 할당을 받고 0으로 초기화 한다.
우선 함수의 선언을 보면 아래와 같다.
void *malloc(size_t size);
void *calloc(size_t num, size_t size);
malloc은 메모리를 할당받을 사이즈 하나만을 파라미터로 받는 반면
calloc은 메모리를 할당받을 사이즈에 그 메모리를 몇개를 할당 받을지 갯수도 파라미터로 받는다.
둘다 void 포인터를 반환하는데 그 이유는 할당한 메모리를 어떤 크기로 잘라서 사용할지는 그때그때 다르기 때문에 사용자가 강제형변환을 통해 사용하면 되기 때문이다.
아래 간단한 예제를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> #include <stdlib.h> int main() { int *pi1; int *pi2; pi1 = (int *)malloc(sizeof(int) * 3); //할당 pi1[0] = 1; pi1[1] = 5; pi1[2] = 8; pi2 = (int *)calloc(3, sizeof(int)); //할당 pi2[0] = 1; pi2[1] = 5; pi2[2] = 8; free(pi1); //메모리 해제 free(pi2); //메모리 해제 } | cs |
바로 calloc은 메모리를 할당과 동시에 0으로 초기화 하는 것이다.
아래 예제를 보자. 모두 할당만 하고 값을 출력시켜 보았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> #include <stdlib.h> int main() { int *pi1; int *pi2; pi1 = (int *)malloc(sizeof(int) * 3); //할당 printf("malloc : %d %d %d\n", pi1[0], pi1[1], pi1[2]); pi2 = (int *)calloc(3, sizeof(int)); //할당 printf("calloc : %d %d %d\n", pi2[0], pi2[1], pi2[2]); free(pi1); //메모리 해제 free(pi2); //메모리 해제 } | cs |
출력결과
malloc : -842150451 -842150451 -842150451
calloc : 0 0 0
할당하면서 0으로 초기화가 되기때문에 상황에 따라 편리할 수 있다.
realloc에대해서 알아보자.
realloc은 malloc이나 calloc으로 할당받은 메모리의 사이즈를 변경할 때 사용한다.
함수선언은 아래와 같다.
void *realloc(void *block, size_t size);
파라미터로 기존에 할당받았던 메모리를 전달하고 다음 파라미터로 새로 할당 받을 size를 전달한다.
아래 예제를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdio.h> #include <stdlib.h> int main() { int i; int *pi = (int *)malloc(sizeof(int) * 3); //4x3 메모리 할당 for (i = 0; i < 3; i++) pi[i] = i * 4; for (i = 0; i < 3; i++) printf("pi[%d] : memory %d %d\n", i, &pi[i], pi[i]); printf("-----------------------------\n"); pi = (int *)realloc(pi,sizeof(int) * 5); //4x5 메모리 재할당 for (i = 3; i < 5; i++) pi[i] = i * 4; for (i = 0; i < 5; i++) printf("pi[%d] : memory %d %d\n", i, &pi[i], pi[i]); printf("-----------------------------\n"); free(pi); //메모리 해제 } | cs |
출력결과
pi[0] : memory 9457232 0
pi[1] : memory 9457236 4
pi[2] : memory 9457240 8
-----------------------------
pi[0] : memory 9457232 0
pi[1] : memory 9457236 4
pi[2] : memory 9457240 8
pi[3] : memory 9457244 12
pi[4] : memory 9457248 16
-----------------------------
처음 4X3 메모리를 할당받았고 그다음에는 4X5 메모리를 재할당 받았다.
재할당 받은 뒤에 기존에 할당받았던 값 이외에 값인 4번째, 5번째에만 값을 넣어준다.
재할당 받은 뒤에도 기존에 값은 정상적으로 존재하는 것을 확인할 수 있다.
단순히 메모리 사이즈만 변경하는 것이 아닌 내용물도 복사를 한다.
그리고 메모리의 주소값이 같은것을 볼 수 있는데 이것은 보장하지는 않는다.
완전 새로운 메모리에 값을 새로 할당받아 값을 복사할 수도 있다.
아래 예제를 보자. 메모리를 기존보다 훨씬 크게 할당한 것을 볼 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdio.h> #include <stdlib.h> int main() { int i; int *pi = (int *)malloc(sizeof(int) * 30000); // 메모리 할당 for (i = 0; i < 3; i++) pi[i] = i * 4; for (i = 0; i < 3; i++) printf("pi[%d] : memory %d %d\n",i,&pi[i],pi[i]); printf("-----------------------------\n"); pi = (int *)realloc(pi,sizeof(int) * 5000000); // 메모리 재할당 for (i = 3; i < 5; i++) pi[i] = i * 4; for (i = 0; i < 5; i++) printf("pi[%d] : memory %d %d\n", i, &pi[i], pi[i]); printf("-----------------------------\n"); free(pi); //메모리 해제 } | cs |
출력결과
pi[0] : memory 17674192 0
pi[1] : memory 17674196 4
pi[2] : memory 17674200 8
-----------------------------
pi[0] : memory 21880896 0
pi[1] : memory 21880900 4
pi[2] : memory 21880904 8
pi[3] : memory 21880908 12
pi[4] : memory 21880912 16
-----------------------------
메모리의 주소값이 달라진 것을 볼 수 있다. 하지만 0, 4, 8은 잘 복사된 것을 볼 수 있다.
'C, C++' 카테고리의 다른 글
C언어/C++ 랜덤(난수)함수 사용법 및 로또 번호 추첨 예제 (0) | 2018.06.29 |
---|---|
C/C++ malloc, free를 사용한 메모리 할당 및 해제(1차원, 2차원 배열) (0) | 2018.06.17 |
C언어/C++ 콘솔 화면 초기화 방법, 예시 (0) | 2018.06.04 |
C언어/C++ 딜레이 함수 Sleep(), 설명, 사용예시 (0) | 2018.06.04 |
C,C++ 콘솔화면에 원하는 좌표로 커서 이동하기 (0) | 2018.06.02 |