struct _BUFFER_INFO
{    
    BUFFER_MANAGER                stBM;                
    pBuffer[1];           
}; 
_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의 초기화는 이렇게 되었어야 합니다.
static PBUFFER_INFO            g_pBI;        
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;
}
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]이라면 어떻게 될까요?

static PBUFFER_INFO            g_pBI;    
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[] 도 가능합니다.
신고
Write your message and submit
« PREV : 1 : ··· : 25 : 26 : 27 : 28 : 29 : 30 : 31 : 32 : 33 : ··· : 228 : NEXT »