2009년 04월 29일
재미있는 C언어4. char pBuffer[1]의 역할은?
  1. struct _BUFFER_INFO
    {
        BUFFER_MANAGER                stBM;                // buffer manager
        char                        pBuffer[1];            // global buffer cache buffer
    };

 

_BUFFER_INFO는 buffer cache의 전체정보를 담고 있는 자료구조로 크게 entry들을 관리하는 BUFFER_MANAGER와 실제 data가 저장되는 pBuffer로 나뉘어 있습니다.

 

char pBuffer[1]를 유심히 살펴 보세요. 엥? 이건 무슨 코드인가요?

왜 char *pBuffer 라고 하지 않았을까요?

 

BUFFER_INFO는 buffer cache가 초기화 될 때 전체 메모리를 할당 받게 됩니다. 

만약 char pBuffer[1]이 아닌 char* pBuffer였다면 BUFFER_INFO의 초기화는 이렇게 되었어야 합니다.

  1. static PBUFFER_INFO            g_pBI;       
  2. g_pBI = RtlAllocMem(sizeof(BUFFER_INFO));
    IF (NULL == g_pBI)
    {
       NSD_CMZ((_T("g_pBI allocation fail, ERR[%d]"), err));
       err = FERROR_INSUFFICIENT_MEMORY;
       break;
    }
  3. g_pBI->pBuffer = RtlAllocMem(BCACHE_SIZE);
    IF (NULL == g_pBI->pBuffer)
    {
        NSD_CMZ((_T("g_pBI->pBuffer allocation fail, ERR[%d]"), err));
        RtlFreeMem(g_pBI);
        g_pBI = NULL;
        err = FERROR_INSUFFICIENT_MEMORY;
        break;
    }

즉, BUFFER_INFO와 pBuffer의 메모리를 두번 할당 받아야 합니다. 물론 해제 할때도 마찬가지 입니다.

 

char pBuffer[1]이라면 어떻게 될까요?

  1. static PBUFFER_INFO            g_pBI;   
  2. g_pBI = RtlAllocMem(sizeof(BUFFER_INFO)+ BCACHE_SIZE);
    IF (NULL == g_pBI)
    {
        NSD_CMZ((_T("g_pBI allocation fail, ERR[%d]"), err));
        err = FERROR_INSUFFICIENT_MEMORY;
        break;
     }

메모리 할당이 한번으로 끝났습니다.  중요한점은 BUFFER_INFO와 pbuffer가 메모리상으로 한덩어리로 잡힌다는 것입니다.

이러한 접근은 메모리 할당을 두번에서 한번으로 줄인것 말고도 좋은 점이 있습니다.

만약 이 BUFFER_INFO를 Log와 같이 File에 주기적으로 저장을 한다고 하면 어떨까요? char *pBuffer 로 사용했을 경우는 이 자료구조에 두번 접근해야 합니다. 필요없는 memcpy도 수반될 수 있습니다. 또한, BUFFER_INFO 와 pBuffer가 메모리 상으로 떨어져 있기 때문에 CPU에서 cache miss가 발생하는 확률도 높아집니다.

 

char pBuffer[1];

별거아닌거 같지만, 코드도 짦아지고, 수행시간도 짧아질 수 있어 좋은 테크닉인 것 같습니다.

char pBuffer[0]도 의미는 유효하지만, C90표준에서는 허용하지 않고 있습니다. 일부 컴파일러는 경고나 에러를 낼 수도 있습니다.

 

ps. 하지만, 가독성은 좀 떨어지네요. ㅎㅎ

ps2. C99 표준에서는 가변길이 배열을 허용하고 있습니다. 즉, char pBuffer[] 도 가능합니다.

 

 

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

by buzzan | 2009/04/29 10:54 | 재미있는 C언어 | 트랙백 | 덧글(0)
트랙백 주소 : http://buzzan.egloos.com/tb/4330351
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글



<< 이전 페이지 | 다음 페이지 >>