본문 바로가기

C/개념

C언어의 메모리 동적 할당

반응형
SMALL

C언어에서 제공하는 malloc, calloc, realloc 함수를 이용한 메모리 동적할당을 알아보도록 하겠습니다.


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 <stdio.h>
#include <stdlib.h>

int main() {
	int arr_1[5]; // 배열 선언
    int *arr_2; // 포인터 변수 선언
    int i;
    
    for (i = 0; i < 5; i++) {
    	arr1[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 개 만큼 저장할 수 있는 메모리 공간을 할당하라는 의미를 가집니다.

#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)
    arr_2 = (int*) calloc(5, sizeof(int)); // sizeof(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을 쓰면 편합니다.


이상 C언어의 메모리 동적 할당이었습니다. ^_^

반응형
LIST

'C > 개념' 카테고리의 다른 글

Hash 구현  (0) 2019.08.18
Hash 알고리즘  (0) 2019.08.10
C언어의 메모리 구조  (2) 2019.06.23
포인터(Pointer) .. 왜 쓸까요? (2)  (0) 2019.06.20
포인터(Pointer) .. 왜 쓸까요? (1)  (0) 2019.06.19