-
[C] malloc, calloc, realloc을 이용한 메모리 동적 할당Programming/C언어 2014. 6. 26. 00:31반응형
동적할당을 사용하는 이유는 무엇일까?
c언어의 메모리 구조에 대해서 알고 있다면 동적할당을 사용하는 이유를 쉽게 알 것이다.
2014/06/26 - [Programming/C언어] - [C] 스택(Stack), 힙(Heap), 데이터(Data)영역
malloc 함수
- 동적으로 메모리를 할당하는 함수 (힙 영역에 메모리를 할당)
#include <stdlib.h> void* malloc(size_t size) // malloc 함수의 원형
함수 호출시 할당하고자 하는 메모리의 크기를 바이트 단위로 전달하면 그 크기만큼 메모리를 할당하게 된다.
그리고 할당한 메모리의 주소(첫 번째 바이트의 주소)를 리턴한다.
메모리 할당에 실패하면 NULL이 리턴된다.
리턴형이 void*(void 포인터) ??
malloc은 단순히 메모리만 할당하는 함수이기 때문에 개발자가 어떠한 데이터 형을 저장하는지 예측할 수 없다.
예를들어 4바이트를 할당하였을 경우 int형 데이터를 저장하기 위해서 사용하는지, float형 데이터를 사용하는지 예측할 수 없기 때문에 void포인터를 반환하여 개발자가 알맞은 용도로 변환하여 사용할 수 있도록 만든것이다.
예를들어 int형 데이터를 저장하기 위해서는 리턴되는 void*을 int*로 변환해야 한다.
int *i = (int*) malloc (sizeof(int));
위의 그림은 포인터 변수 i에 4바이트를 할당하는 그림이다.
1. sizeof(int)의 값은 4이다. 4라는 값을 전달하면서 malloc 함수를 호출한다.
2. 할당된 메모리의 주소가 void*형으로 리턴된다. 리턴되는 void*를 사용하려는 int*형으로 변환한다.
3. 포인터 변수 i에 대입한다.
malloc함수 사용 예
동적 할당을 사용하여 arr_1의 배열의 값을 대입하는 소스를 보며 malloc함수 사용법을 이해해보자.
#include <stdio.h> #include <stdlib.h> int main() { int arr_1[5]; // 배열 선언 int *arr_2; // 포인터 변수 선언 int i; for(i = 0; i < 5; i++) { arr_1[i] = i+1; // 배열에 값 대입 } arr_2 = (int*) malloc(sizeof(int)*5); // 메모리 할당, 배열의 크기만큼 할당하기 위해 5를 곱함 for(i = 0; i < 5; i++) { arr_2[i] = arr_1[i]; printf("%d ", arr_2[i]); } return 0; }
free 함수
- 힙 영역에 할당된 메모리를 해제하는 함수
메모리를 할당만 하고 해제해 주지 않는다면, 언젠가는 메모리가 부족한 현상이 발생 할 것이다.
할당된 메모리가 더 이상 필요하지 않을경우 free함수를 이용하여 메모리를 해제시켜 줘야한다.
#include <stdlib.h> void free(void* ptr) // free 함수의 원형
free함수 사용 예
위의 예제에서 free함수만 추가시켰다.
#include <stdio.h> #include <stdlib.h> int main() { int arr_1[5]; // 배열 선언 int *arr_2; // 포인터 변수 선언 int i; for(i = 0; i < 5; i++) { arr_1[i] = i+1; // 배열에 값 대입 } arr_2 = (int*) malloc(sizeof(int)*5); // 메모리 할당, 배열의 크기만큼 할당하기 위해 5를 곱함 for(i = 0; i < 5; i++) { arr_2[i] = arr_1[i]; printf("%d ", arr_2[i]); } free(arr_2); // free함수를 이용하여 메모리 해제 return 0; }
calloc 함수
- calloc함수는 malloc함수와 같은 기능을 지니고 있다. 다만 사용하는 형태가 조금 다를 뿐이다.
#include <stdlib.h> void* calloc(size_t elt_count, size_t elt_size) // calloc 함수 원형
calloc 함수는 elt_size 크기의 변수를 elt_count 개 만큼 저장할 수 있는 메모리 공간을 할당하라는 의미를 갖는다.
calloc함수 사용 예
위의 예제에서 malloc 함수대신 calloc 함수를 사용하였다.
#include <stdio.h> #include <stdlib.h> int main() { int arr_1[5]; // 배열 선언 int *arr_2; // 포인터 변수 선언 int i; for(i = 0; i < 5; i++) { arr_1[i] = i+1; // 배열에 값 대입 } //arr_2 = (int*) malloc(sizeof(int)*5); // 메모리 할당, 배열의 크기만큼 할당하기 위해 5를 곱함 arr_2 = (int*) calloc(5, sizeof(int)); // sizoe(int)크기의 변수를 5개 저장할 수 있는 공간할당 for(i = 0; i < 5; i++) { arr_2[i] = arr_1[i]; printf("%d ", arr_2[i]); } free(arr_2); // free함수를 이용하여 메모리 해제 return 0; }
malloc함수와 calloc함수의 차이점!
malloc은 할당된 공간의 값을은 바꾸지 않는다.
calloc은 할당된 공간의 값을 모두 0으로 바꾼다.
배열을 할당하고 모두 0으로 초기화할 필요가 있을경우에는 calloc을 쓰면 편하다.
realloc 함수
- 이미 할당한 공간의 크기를 바꿀 때 realloc 함수를 사용한다.
#include <stdlib.h> void* realloc(void* memblock, size_t size); // realloc 함수의 원형
이미 할당한 포인터 변수를 memblock에 넣고, 바꾸고 싶은 공간의 크기를 size에 입력하여 사용한다.
realloc함수 사용 예
malloc함수를 사용한 예제에서 realloc 함수를 사용하여 변경하였다.
#include <stdio.h> #include <stdlib.h> int main() { int arr_1[10]; // 배열 선언 int *arr_2; // 포인터 변수 선언 int i; for(i = 0; i < 10; i++) { arr_1[i] = i+1; // 배열에 값 대입 } arr_2 = (int*) malloc(sizeof(int)*5); // 메모리 할당, 배열의 크기만큼 할당하기 위해 5를 곱함 for(i = 0; i < 5; i++) { arr_2[i] = arr_1[i]; printf("%d ", arr_2[i]); } printf("\n"); // sizeof(int) = 4바이트 realloc(arr_2, sizeof(int)*10); // arr_2의 메모리를 40바이트로 재 할당 // arr_2의 메모리 크기 : 20바이트 -> 40바이트 for(i = 0; i < 10; i++) { arr_2[i] = arr_1[i]; printf("%d ", arr_2[i]); } free(arr_2); // free함수를 이용하여 메모리 해제 return 0; }
반응형'Programming > C언어' 카테고리의 다른 글
[C] 스택(Stack), 힙(Heap), 데이터(Data)영역 (26) 2014.06.26 [C] Log2 (밑이 2인 로그 함수) 구하기 (11) 2014.03.28 [C] C언어 M_PI 사용하기 (3) 2014.03.26