동적 메모리 - 메모리 할당 | c Note 2004/09/07 12:21
http://blog.naver.com/bravedog/100005577911

베열을 이용한 메모리 할당은 프로그램이 실행되기 전부터 이미 메모리의 크기가 정해져 있다. 하지만 필요에 따라 실시가능로 필요한 메모리의 크기를 설정하여 할당해야 할 경우가 있다. 이렇나 경우 피룡한 것이 동적 메모리 할당이다. 동적 메모리 할당은 메모리 할당 함수 malloc 또는 calloc을 이용하여 메모리를 할당하고 해당 메모리에 접근하기 위해서 포인터를 사용한다. 메모리의 크기를 변경하기 위해서는 realloc함수를 사용하고, 마지막으로 할당한 메모리를 제거하기 위해서는 free함수를 사용한다.

 

단 동적 메모리 할당 시에 주의할 점은 사용이 끝난 메모리는 반드시 free함수를 통하여 해제시켜 주어야 한다는 것이다. 그렇지 않으면 프로그램이 종료한 후에도 메모리가 해제되지 않아 사용 가능한 메모리 공간이 줄어들게 된다. 최악의 경우 메모리 부족으로 시스템 오류가 발생할 수도 있다.

 

메모리 할당

 

메모리 할당 함수 malloc과 calloc에 관해서 살펴보자. amlloc과 calloc은 alloc.h또는 stdlib.h에 선언되어 있다. 메모리를 할당한다는 측면에서 두 함수는 유사하나 malloc은 할당된 메모리의 초기화를 하지 않는 반면 calloc은 할당된 메모리를 0으로 초기화를 하는 차이점이 있다.

 

먼저 malloc을 살펴보자. malloc함수의 원형은 다음과 같다.

 

void *malloc(size_t size);

 

malloc은 메모리 힙으로부터 size 바이트 크기의 메모리를 할당하고 그 시작번지의 포인터를 리턴하는 함수이다. 메모리 할당에 성공하였을 경우 할당된 주소의 void 형 포인터가 리턴되며 실패한 경우에는 NULL포인터가 리턴된다.

 

이렇게 리턴된 void 형 포인터를 접근하기 위해서는 앞서 void 형 포인터에서 배운 바와 같이 타입캐스팅이 필요할 수도 있다. 실제로 에전의 C언어는 타입캐스팅이 없으면 경고 메시지를 보내었다. 하지만 현재 ANSI C표준에 의하면 타입캐스팅이 있던 없던 경고를 띄우지 않는다. 따라서 타입캐스팅이 없이 바로 사용할 수 있다.

 

 1  #include <stdio.h>
 2  #include <stdlib.h>         // alloc.h를 써도 무관
 3
 4  int main()
 5  {
 6      int i;
 7      size_t *pEven;
 8
 9      // int 형(2byte) * 10개 = 20 byte
10      pEven = (size_t*)malloc(100);
11
12      // 메모리 할당에 실패했을 경우 프로그램 종료
13      if(!pEven)
14          return EXIT_FAILURE;
15      for(i=0;i<10;i++)
16          pEven[i] = i+1;     // 자연수는 첨자보다 1크다
17
18      printf("짝수 : ");
19      for(i=0;i<10;i++)
20          // 짝수 체크
21          if(pEven[i]%2==0)
22              printf("%d ",pEven[i]);
23      printf("\n");
24
25      // 메모리 해제(반드시)
26      free(pEven);
27
28      return EXIT_SUCCESS;
29  }
30
31  /*---------------------------------------------------------
32   * malloc을 이용하여 메모리를 할당 받을 때에는 필요로 하는
33   * 메모리의 크기를 정확히 알아야 한다.
34   * 하지만 위의 예와 같이 특정 데이터 형을 특정 개수만큼
35   * 받는다면 데이터 형의 크기를 알 수 있는 sizeof연산자를
36   * 사용하여 다음과 같이 사용할 수도 있다.
37   *
38   * int형(2byte) * 10개 = 20byte
39   * pEven = (int*)malloc(10*sizeof(int));
40   *
41   * 동적 메모리 할당에 있어 주의해야 할 점이 또 하나 있다.
42   * 그것은 바로 메모리 할당이 실패하는 경우이다.
43   *
44   * 메모리 할당에 실패했을 경우 프로그램 종료
45   *  if(!pEven)
46   *          return EXIT_FAILURE;
47   *
48   *  만일 메모리 할당에 실패했을 경우 처리하는 구문이 없다면
49   *  프로그램은 마치 메모리가 할당된 것처럼 주소를 접근한다. 
50   *  이러한 경우 프로그램의 실행중 치명적인 오류가 발생한다.
51   *--------------------------------------------------------*/

 

결과화면

 

 

 

 

 

 

 

 

그러면 이번에는 calloc함수를 살펴 보자. 앞에서도 언급하였지만 calloc은 malloc과 달리 할당된 메모리를 0으로 초기화한다고 하였다. 먼저 calloc의 원형을 보도록 하자

 

void *calloc(size_t nitems, size_t size);

 

calloc는 nitems*size 바이트 크기의 메모리를 할당하고, 할당된 메모리를 모두 0으로 초기화하는 함수이다. 리턴값은 malloc과 마찬가지로 성공할 경우 할당된 메모리의 시작주소의 void 형 포인터를, 실패할 경우 NULL 포인터를 리턴한다. 할당 시 초기화가 가능하다는 점에서 malloc 보다 선호하는 경우도 많다.

 

다음 예제 프로그램을 통하여 calloc을 이용한 동젝 메모리 할당을 해보자. 20이하의 자연수 중에서 3의 배수를 출력하는 프로그램이다.

 1  #include <stdio.h>
 2  #include <stdlib.h>         // alloc.h를 써도 무관
 3
 4  int main()
 5  {
 6      int i;
 7      int *pEven;
 8
 9      // int 형(2byte) * 10개 = 20 byte
10      pEven = (int*)calloc(20,sizeof(int));
11
12      // 메모리 할당에 실패했을 경우 프로그램 종료
13      if(!pEven)
14          return EXIT_FAILURE;
15
16      // 초기값 출력
17      printf("초기값\n");
18      for(i=0;i<20;i++)
19          printf("%d ",pEven[i]);     // calloc은 0으로 초기화된다
20
21      for(i=0;i<20;i++)
22          pEven[i] = i+1;             // 자연수는 첨자보다 1크다
23
24      printf("\n20이하의 3의 배수 : \n");
25      for(i=0;i<20;i++)
26          // 3의 배수 체크
27          if(pEven[i]%3==0)
28              printf("%d\n",pEven[i]);
29
30      // 메모리 해제(반드시)
31      free(pEven);
32
33      return EXIT_SUCCESS;
34  }

 

결과 화면

Posted by 김용환 '김용환'

댓글을 달아 주세요