[C] 동적 메모리 할당 및 해제

2021. 1. 8. 17:58프로그래밍 공부/C 공부

정적 메모리 할당의 한계

컴파일러의 디폴트 스택 메모리 크기는 1메가 바이트이다.

 

컴파일 될 당시 스택 메모리가 1메가 바이트를 넘는다면 오류가 출력된다.

컴파일 될 당시 스택 메모리가 1메가 바이트를 넘지 않는다면 오류가 출력되지 않지만, 프로그램이 실행되면서 함수가 어려번 호출되어 결과적으로 스택 메모리가 1메가 바이트를 넘어설 수 있고, 그럴 경우 오류가 출력된다.

아무튼 1메가 바이트를 넘으면 안되는데 그걸 알기가 힘들다

 

하지만 모니터에 출력되는 픽셀 한점이 4바이트이고, FULL-HD는 1920 x 1080 픽셀이기 때문에 7 메가 바이트정도 되는 용량이다. 결국 프로세스 안에 할당된 스택 메모리로는 FULL-HD 영상 한 장면조차 담지 못한다.

 

동적 메모리 할당

정적 메모리 할당과는 다르게 컴파일시 메모리가 할당되는것이 아니라 프로그래머가 원할때, 원하는 만큼 메모리를 할당할 수 있는 기능. 기가 바이트 단위까지 할당할 수 있다.

 

malloc 함수 : 동적 메모리 할당

malloc은 동적 메모리 할당을 지원하는 C 표준 함수이다. 

사용자가 size 변수를 지정해주면 그 만큼 heap 영역에 메모리를 할당하고 그 할당된 주소로 void * 형식으로 반환해준다. 즉 malloc 함수는 원하는 크기의 메모리 공간을 확보하고 그 주소를 반환하는 것이다.

 

(1) malloc 함수의 사용

#include <malloc.h> // malloc 등의 함수가 포함된 라이브러리
함수 원형 : void *malloc(size_t size); // size_t 는 unsigned int와 같은 자료형
사용 형식 : void *p = malloc(100); // 100byte의 메모리를 할당하여 포인터 p에 저장함

그런데 void 형으로 지정하는것이 의미하는것은 뭘까? 

void 형으로 100바이트를 할당하는 것은 100바이트가 1바이트씩 100개, 2바이트씩 50개, 4바이트씩 25개 그룹으로 나뉠지 정하지 못했다는 것을 말한다. 

 

만약 미리 정했다면? 아래와 같이 할당되는 메모리에 형변환을 해주면 된다.

char *p = (char *)malloc(100);
short *p = (short *)malloc(100);
int *p = (int *)malloc(100);

 

(2) malloc 함수의 할당 실패

malloc 함수가 heap의 범위를 넘어선 메모리를 할당할 때는 메모리 할당에 실패한다.

이때 malloc 함수는 메모리 주소 대신  NULL을 반환한다.

따라서 malloc 함수를 사용할때는 오류를 체크하는 코드를 같이 쓰는게 좋다. 

 

short *p = (short *)malloc(100);
if(NULL != p) {//메모리 할당에 성공한 경우}
else {//메모리 할당에 실패한 경우} 

 

free함수 : 메모리 해제

스택에 할당된 지역 변수 메모리는 함수가 끝나면 자동으로 해제되지만 힙(heap)에 할당된 메모리는 프로그램이 끝나지 않으면 자동으로 해제되지 않는다. 따라서 free함수를 써서 명시적으로 해제해야한다.

 

(1) free 함수 사용

free(p); // p 가 가지고있는 주소에 할당된 메모리를 해제

(1) free 함수 오류

1. 할당되지 않은 메모리를 해제하는 경우 : 컴파일은 성공하더라도 실행때 오류가 나옴

2. 정적으로 할당된 메모리를 해제하는 경우 : 실행시 오류 발생

3. 할당된 메모리를 두번 해제하는 경우 : 1번과 같은 오류 

 

malloc 함수 : 메모리 손실

아래와 같은 코드는 Trail 함수가 실행될 때마다 100메가 바이트의 메모리가 heap에 추가되는데 free로 해제하지 않아서 100 메가바이트 * 100의 메모리가 heap에 묶이게 된다. 게다가 Trial 변수에 선언된 포인터 p는 지역변수이기 때문에 Trial 함수가 종료되면서 그 값이 사라진다. 

 

결국 100메가 바이트를 저장한 주소값 p가 사라지기 때문에 메모리 주소를 알 방법이 없어서 해당 메모리를 해제할 방법도 없어진다. 이러한 상태를 메모리 손실이라고 한다.

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

void Trial();

void main()
{
	int i ;
    for(i=0 ; i < 100 ; i++) Trial();
}

void Trial() 
{
	short *p = (short *)malloc(100);
    // free *p
}

 

'프로그래밍 공부 > C 공부' 카테고리의 다른 글

[C] 공부 소스  (0) 2021.01.12
[C] 동적메모리 사용하기  (0) 2021.01.10
[C] 프로세스와 메모리할당  (0) 2021.01.08
[C] 배열과 포인터 2  (0) 2021.01.08
[C] 배열과 포인터  (0) 2021.01.07