To implement a fixed length buffer with head and tail pointers
I am implementing a buffer of fixed length to read or write a string开发者_Python百科 using a tail or head pointer respectively. I have the following code:
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;
}
This code works until maximum buffer is hit, when head pointer starts again, tail pointer is not placed properly.
Any suggestions in improving the code, apart from finding the bugs?
With a circular buffer, there are at least two ways to distinguish a full state from an empty one (head == tail
in both those cases).
Allow for one more item in the buffer than you actually need and don't ever let
head
advance totail
when adding (raise a "buffer full" error instead). That way,head == tail
always means empty.Maintain a "free slots" variable as well as the head and tail, initialising it to the size of the buffer, decrementing it when adding and incrementing when removing. That way you can detect buffer full by the fact that it's set to zero, or buffer empty if it's set to the original size.
For option 1, something like:
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
For option 2, something like:
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
精彩评论