2011-04-26 80 views
0

我正在實現一個固定長度的緩衝區,分別使用尾部或頭部指針來讀取或寫入字符串。我有以下代碼:實現具有頭部和尾部指針的固定長度緩衝區

bool putBuffer(char *sMsz) 
{ 
int iStrLen; 
iStrLen = strlen(sMsz); 
if(!iStrLen || iStrLen>MAX_LEN) 
return 0; 
    while(iStrLen-->=0) 
{ 
    //if head crosses tail 
    if(iBufHead==iBufTail && iBufHead!=0 && dFlag) 
    { 
    while(cDebugBuf[iBufTail] != '\0') 
    { 
     iBufTail=iBufTail+1; 
     if (iBufTail>=CBUFF_SIZE) 
     iBufTail = 0; 
    } 
    iBufTail++; 
    } 
    if(iBufHead>=CBUFF_SIZE) 
    { 
    dFlag=1; // Used to know when buffer starts over writing prev data and meets tail on     way 
    iBufHead = 0; 
    } 
    cDebugBuf[iBufHead++] = *(sMsz++); 
} 
return 1; 
} 

bool getBuffer(char *readData) 
{ 
    int i=0; 
    do 
    { 
    if(iBufTail==iBufHead) 
     return 0; 
    if(iBufTail>=CBUFF_SIZE) 
    iBufTail = 0; 
    readData[i++] = cDebugBuf[iBufTail++]; 
    }while(cDebugBuf[iBufTail]!='\0'); 
    iBufTail++; 
    return 1; 
} 

此代碼一直運行,直到最大緩衝區命中,當頭指針再次啓動時,尾指針未正確放置。

改進代碼的任何建議,除了發現錯誤嗎?

回答

1

對於循環緩衝區,至少有兩種方法可以區分完整狀態和空白狀態(在這兩種情況下爲head == tail)。

  1. 比你的實際需要,也不要讓head提前tail增加時(養「緩衝區已滿」錯誤代替)緩衝區允許一個以上的項目。這樣,head == tail總是表示空。

  2. 維護一個「空閒插槽」變量以及頭部和尾部,將其初始化爲緩衝區的大小,在刪除時添加並遞增時遞減。這樣,您可以通過設置爲零的事實來檢測緩衝區已滿,或者如果設置爲原始大小,則緩衝區爲空。


對於第一種情況,是這樣的:

def buffInit(sz): 
    global buffSz = sz 
    global buffData = alloc(buffSz+1)   # allow for extra slot. 
    global buffHead = 0 
    global buffTail = 0 

def buffAdd(item): 
    if (buffHead + 1) % buffSz == buffTail: # never fill extra slot. 
     return BUFFER_FULL 
    buffData[buffHead] = item 
    buffHead = (buffHead + 1) % buffSz 
    return OK 

def buffGet(): 
    if buffHead == buffTail: 
     return BUFFER_EMPTY 
    item = buffData[buffHead] 
    buffHead = (buffHead + 1) % buffSz 
    return item 

對於第二種情況,是這樣的:

def buffInit(sz): 
    global buffSz = sz 
    global buffFree = buffSz     # extra information. 
    global buffData = alloc(buffSz) 
    global buffHead = 0 
    global buffTail = 0 

def buffAdd(item): 
    if buffFree == 0:       # zero free slots means full. 
     return BUFFER_FULL 
    buffData[buffHead] = item 
    buffHead = (buffHead + 1) % buffSz 
    buffFree = buffFree - 1     # keep in sync. 
    return OK 

def buffGet(): 
    if buffFree == buffSz: 
     return BUFFER_EMPTY 
    item = buffData[buffHead] 
    buffHead = (buffHead + 1) % buffSz 
    buffFree = buffFree + 1     # keep in sync. 
    return item