자료실/C언어

C언어 - 동적 메모리 할당

자료수집중 2020. 8. 7.
반응형

 

 

보통 배열의 크기를 컴파일 전에 선언해 두고 사용합니다.

가장 많이 사용하는 방법으로 보통 '정적 메모리 할당'이라고 합니다.

이 경우에는 미리 선언해 두고 해제할 필요가 없다는 장점이 있지만 반대로 미리 선언했기 때문에 비효율적일 수도 있습니다.

예를 들어 100의 크기의 배열을 선언했지만 막상 필요한 크기는 20이 되면 80은 낭비가 됩니다.

그래서 '동적 메모리 할당'을 이용해서 적절하게 메모리를 관리해야 할 경우가 발생합니다.

 

먼저 동적 메모리 할당을 하기 위해서는 새롭게 라이브러리를 추가해야 합니다.

#include <stdlib.h>

 

 

이제 동적 메모리 할당에 필요한 함수에 대해 알아보겠습니다.

malloc()

void *malloc(size_t _Size);

인자로 전달받은 크기만큼의 메모리를 할당합니다.

void에는 반환 타입이 입력됩니다.

1 = 1byte의 크기를 할당해줍니다 ex) malloc(100) -> 100byte의 크기를 할당

#include <stdio.h> 
#include <stdlib.h>
#include <malloc.h>

int main(void)
{
	int value;
	char *arr_1;
	printf(" 몇글자를 입력하시겠습니까? ");
	scanf("%d", &value);
    
	arr_1 = (char*)malloc(sizeof(char)*value);
	printf("arr_1의 크기는 = %d \n", _msize(arr_1));
    
	free(arr_1);
	return 0;
}

메모리 할당에서 크기를 지정할 때 직접 크기를 적어도 되지만 sizeof()를 이용해서 자료형의 크기를 구해서 할당해줄 크기를 정하는 방법을 많이 사용합니다.

malloc.h는 동적 메모리 할당된 변수의 크기를 구하기 위한  _msize()를 사용하기 위한 라이브러리입니다. sizeof()를 이용해서 구하면 4의 값만 주어집니다. 이 값은 포인터 변수는 주소를 저장하기 때문에 기본적으로 4byte의 크기를 가지기 때문입니다.

malloc으로 할당된 메모리는 초기화를 하지 않습니다. 바로 출력해보면 쓰레기 값이 들어 있습니다.

만약 할당이 실패하면 NULL을 반환합니다.

 

 

free()

void free(void *p);

할당된 메모리를 해제해줍니다.

동적 메모리는 사용 후 꼭 해제를 해야 합니다. 만약 해제를 안하게 되면 메모리 누수가 발생합니다.

인자로 동적 할당이 된 포인터를 입력하면 해제가 됩니다.

#include <stdio.h> 
#include <stdlib.h>

int main(void)
{
	int *arr_1;

	arr_1 = (int*)malloc(sizeof(int)*10);
	free(arr_1);

	return 0;
}

 

 

calloc()

void *calloc(size_t n, size_t size);

calloc()도 동적 메모리를 할당하는 함수이지만 malloc()하고는 다르게 인자가 2개이고 메모리를 전부 0으로 초기화해줍니다.

calloc의 첫 번째 인자는 할당할 메모리 개수입니다. 두 번째 인자는 각 할당된 메모리의 크기입니다. 예를 들어 (int*)malloc(sizeof(int)*10);을 calloc()으로 사용하면 (int*)calloc(10, sizeof(int));입니다.실패하면 NULL을 반환합니다.

#include <stdio.h> 
#include <stdlib.h>

int main(void)
{
	int *arr_1;
	int *arr_2;

	arr_1 = (int*)malloc(sizeof(int)*10);
	arr_2 = (int*)calloc(10, sizeof(int));
	printf("arr_1[0] = %d \n", arr_1[0]);
	printf("arr_2[0] = %d \n", arr_2[0]);

	free(arr_1);
	free(arr_2);
	return 0;
}

 

 

realloc()

void *realloc(void *p, size_t size);

malloc()이나 calloc()으로 할당된 메모리의 크기를 변경하는 함수입니다.

메모리의 크기는 줄이거나 늘리거나 모두 가능합니다.
실패하면 NULL을 반환합니다.

#include <stdio.h> 
#include <stdlib.h>
#include <malloc.h>

int main(void)
{
	int *arr_1;

	arr_1 = (int*)malloc(sizeof(int)*10);

	printf("arr_1의 크기는 = %d \n", _msize(arr_1));
	arr_1 = (int*)realloc(arr_1, sizeof(int) * 12);
	printf("arr_1의 크기는 = %d \n", _msize(arr_1));

	free(arr_1);
	return 0;
}

 

 

2차원 배열 동적 메모리 할당

동적 할당은 1차원이 아니라 2차원, 3차원, 다차원 할당이 가능합니다.

예제로 2차원 배열 동적 할당을 해보겠습니다.

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
	int **arr_1; 
	int arr_size = 10;

	arr_1 = (int**)malloc(sizeof(int)*arr_size);
	for (int i = 0; i < arr_size; i++) {
		arr_1[i] = (int*)malloc(sizeof(int)*arr_size);
	}

	for (int i = 0; i < arr_size; i++) {
		free(arr_1[i]); 
	} 
	free(arr_1); 
	return 0; 
}

2차원 동적 배열은 이중 포인터를 이용해서 1차를 할당하고 다시 반복문을 이용해서 2차를 할당합니다.

해제는 반대로 2차를 해제하고 1차를 해제해야 합니다.

'자료실 > C언어' 카테고리의 다른 글

C언어 - 파일 입출력  (0) 2020.08.05
C언어 - #if, #elif, #else, #endif 와 ifdef, #ifndef, #endif 지시문  (1) 2020.07.22
C언어 - 내장 매크로  (0) 2020.07.21
C언어 - #define  (0) 2020.07.04
C언어 - void 포인터  (0) 2020.07.03

댓글