블로그 이미지
대갈장군

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Notice

2011. 3. 11. 03:20 프로그래밍/Windows API
앞서 언급했던 윈도우 메모리에 관한 이야기 2탄으로 바로 malloc() 함수에 대한 이야기다.

malloc은 뭐 워낙 유명한 함수라서 굳이 이야기 안해도 사용하는 방법쯤은 다 알거라 생각한다. 바로 코드로 들어가 보자.

   
   1:  #include <stdio.h>
   2:  #include <stdlib.h>
   3:  #include <string.h>
   4:   
   5:  #ifdef _DEBUG
   6:  #include <vld.h>
   7:  #include <vldapi.h>
   8:  #endif
   9:   
  10:  void main()
  11:  {
  12:      // Test int
  13:      int *ptr;
  14:      ptr = (int*)malloc(sizeof(int)*10);
  15:   
  16:      for(int i = 0; i < 10; i++)
  17:      {
  18:          ptr[i] = i * 10;
  19:          printf("ptr[%d] = %d\n", i, ptr[i]);
  20:      }
  21:   
  22:      free(ptr);
  23:   
  24:      // Test char
  25:      char *ptr_char;
  26:      ptr_char = (char *)malloc(sizeof(char)*20);
  27:   
  28:      char *str1 = "MEMORY LEAK";
  29:      strcpy(ptr_char, str1);
  30:   
  31:      printf("ptr_char = %s\n", ptr_char);
  32:   
  33:      free(ptr_char);
  34:   
  35:      // Test array of pointers
  36:      int **double_ptr;
  37:   
  38:      double_ptr = (int **)malloc(sizeof(int *)*10);
  39:   
  40:      for(int i = 0; i < 10; i++)
  41:      {
  42:          double_ptr[i] = (int *)malloc(sizeof(int)*10);
  43:          for(int j = 0; j < 10; j++)
  44:          {
  45:              double_ptr[i][j] = (i * 10) + j;
  46:              printf("double_ptr[%d][%d] = %d\n", i, j, double_ptr[i][j]);
  47:          }
  48:      }
  49:   
  50:      for(int i = 0; i < 10; i++)
  51:      {
  52:          free(double_ptr[i]);
  53:      }
  54:   
  55:      free(double_ptr);
  56:   
  57:  }

위의 코드의 제일 윗부분에 라인 6번과 7번을 보면 vld.h 라는 녀석이 있는데 이 녀석은 이른바 visual leak detector라고 불리는 오픈 소스로서 메모리 누수가 발생하면 콘솔 출력창에 어디서 뭐가 왜 어떻게 유출되었는지 상세 정보를 보여주는 아주 착한 놈이다.

이 오픈 소스는 http://www.codeproject.com/KB/applications/visualleakdetector.aspx 에 가면 다운 받을 수 있다.

코드는 세 파트로 나뉘어져 있는데 첫번째 파트에서는 간단하게 10개의 int 메모리를 할당하고 0 에서 9까지 넣어 출력했고 두번째 파트는 char 메모리 공간을 생성하여 MEMORY LEAK라는 섬뜩한 문구를 출력해 봤고 마지막은 이중 포인터를 이용해서 2차원 int 배열을 생성하여 0부터 99까지 각 배열에 대입 후 출력해 봤다.

암튼, 22번 라인, 33번 라인 그리고 50번에서 55번까지 free()로 할당된 메모리를 해제하는 명령들이 나와있는데 메모리는 할당보다 해제가 더 중요하다. 화장은 하는 것보다 지우는 것이 더 중요한 것 처럼... 

예를 들어 두번째 테스트는 Test char 파트에서 free()를 호출 안하면 (라인 33번 지우면), 다음과 같은 에러가 프로그램 종료 후 출력창에 뜬다.


너무나도 친절하게 얼마만큼의 메모리가 누수되었는지 그리고 들어있던 내용은 무엇인지 그리고 게다가 코드의 어느 부분에서 누수가 있었는지 알려준다... 너무 친절해서 눈물이 날 지경이다..

라인 33번에서 55번까지는 이중 포인터의 개념인데 integer 값을 10개 저장하는 배열을 10개 만들었다. 즉, 10 x 10 = 100 개의 int 배열을 만든 셈이다. 중요한 것은 해제인데 해제 할때는 10개의 개별 배열을 모두 하나씩 해제한 후 마지막에 이중 포인터를 해제 한다. 만약 개별 배열들을 해제하지 않고 이중 포인터만 해제해 버리면 10개의 개별 배열은 부모 잃어버린 자식들이 되므로 메모리 누수가 일어난다. 

개별 배열(자식)을 해제 하기 전에 이중 포인터 (부모)를 날려 버리면 자식들을 찾을 수가 없다. 왜냐면 부모 연락처가 없기 때문에... 

malloc을 이용한 할당은 가장 경제적인 메모리 할당이다. 왜냐면 바이트 단위로 사용자가 원하는 만큼 할당하기 때문이다. 좀 있다 살펴볼 다른 메모리 할당 함수는 malloc 처럼 바이트 단위로 할당을 하지 않는다. 경제적인 것은 그만큼 손이 많이 간다. 고로 해제하는 과정을 사용자가 반드시 꼼꼼히 해야 한다는 불편함이 있다. 


posted by 대갈장군