배열의 크기를 할당하기 위해서는 arr[50] 고정된 크기로 할당을 해도되지만은 만약

arr[50] = "hello";
 

배열을 마지막 NULL문자까지 6칸만 사용한다면 나머지 44칸은 낭비되고 말것이다.

 

 

예시를 들어서 사람정보를 저장할수있는 프로그램을 만든다고 생각하자.

이 프로그램은 사람이 많은곳에선 100만명 이상을 저장할수도 있고, 사람이 적은 곳에선 100명만 저장할수도있다.

이 경우에는, 배열 크기를 arr[백만] 주기엔 시골에서 사용되면 많은 메모리 낭비가 될것이고, 백만명 이상일때도 문제가 생길것이다.

이런 경우, 메모리가 얼마나 필요한지 미리 알수없기때문에, 일반적으로 자신이 필요한만큼 메모리를 할당하기위한 동적할당이 필요하다.

int a;
scanf("%d", &a);
int arr[a];
 

(옛날엔) C 에선 변수로 배열길이를 결정해주는 (Variable Length Array) VLA 이런 코드는 되지않는다고 한다.

C99 부터는 위의 코드처럼 가변 길이 배열을 선언할수있게 기능이 추가되었다고하는데 그 전까지는 malloc이란 함수를 사용해서 동적할당을 해주었다.

 

우선 배열에 malloc을 사용하려면 포인터로 선언을 해준다.

malloc 함수는 인수로 필요한 메모리양을 바이트 단위로 전달하면 요청한 만큼 할당한다.

만약 arr 배열에 Hello를 저장하려면 다음와같이하면된다.

char *arr;
arr = (char *) malloc (sizeof(char) * 6);
// arr = {'H', 'E', 'L', 'L', 'O', '\0'};  포인터는 하나씩 접근
arr[0] = 'H';
arr[1] = 'e';
arr[2] = 'l';
arr[3] = 'l';
arr[4] = 'o';
arr[5] = '\0';
free(arr);
 

동적으로 메모리를 할당할때 사용되는 Heap영역의 메모리 상태를 잘 설명해주신분이 있다.

(출저 - https://codingdog.tistory.com/entry/c%EC%96%B8%EC%96%B4-free-%ED%95%A8%EC%88%98-%EC%8C%8D%EC%9D%B4-%EB%A7%9E%EC%95%84%EC%95%BC-%EB%90%9C%EB%8B%A4)

 

메모리를 닫아주지 않으면 필요하지 않은 메모리를 계속 점유하게 되는 메모리 누수 (Memory Leak)현상이 일어난다.

이는 프로그램이 끝날 때 까지 메모리에서 사라지지않는다고 한다.

그래서 반드시 메모리 사용후 free함수를 통하여 메모리 해제를 해주어야한다고한다.

 

그런데 만약 malloc할 메모리가 충분하지않다고 하면 어떻게될까

man malloc을 통한 메뉴얼에 따르면

동적 할당 할 수있는 메모리가있다면 포인터 변수가 할당받은 메모리의 첫번째 위치를 가리키게 될것이고,

동적 할당 할 수있는 메모리가없다면 NULL 포인터를 가리키게 될것이라고한다.

 

그래서 만약 동적 할 수 있는 메모리가 없는데 위의 코드처럼 사용하게된다면 할당되지않은 0번지 주소를 참조하려고 하면서 NULL 포인터 역참조 에러가 나게 될것이다. (물론 위 코드는 6bytes 밖에 할당안했다)

 

따라서 이를 방지하기위해 NULL가드 (NULL 체크)를 해준다.

만약 할당된 메모리가 NULL이면 프로그램을 중지시키는 것이다.

char *arr;
arr = (char *) malloc (sizeof(char) * 6);
if (arr = NULL)
    return ;   // 혹은 exit(); 를 사용하기도 한다.  
 

2차원 배열이면

char **arr;

void free_function(int num){
    for (int i = num - 1; i>=0; i--)
        free(arr[i]);  // 메모리를 arr[0] arr[1] arr[2] 순으로 할당 해주었으면
    free(arr);         // 메모리 해제는 arr[2] arr[1] arr[0] 순으로 해준다. 
}        

int main(){
    arr = (char **) malloc (sizeof(char *) * 5);
    if (arr == NULL)
        return (0);

    for (int i=0; i<5; i++){
        arr[i] = (char *) malloc (sizeof(char) * 5);
        if (arr[i] == NULL){
            free_function(i);
            return (0);
        }
    }

    for (int i=4; i>=0; i--)
        free(arr[i]);
    free(arr);
}
 

 

 

 

물론 현대 컴퓨터, 프로그램으론 malloc함수가 메모리가 부족하여 오류가 발생할 확률은 극히 희박하고 malloc함수가 오류날 정도면 이미 그 시스템은 복구 불가능할 정도의 메모리 상태라는 뜻이기 때문에 차라리 오류가 발생하여 개발자가 빨리 인지하게 만들어 그런 상황이 안나오게 만드는것이 더 좋을수도 있다고 한다. (출저 - https://m.blog.naver.com/tipsware/221712079963)

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

메모리 공간  (0) 2022.04.21
포인터  (0) 2022.03.16

+ Recent posts