2016-03-08 108 views
-1

我遇到了一個我嘗試製作的基本環形緩衝區的問題。 我似乎無法讓它正確包裝。 當我點擊元素數= buffer_length時,行爲變得不可預知,在調試器中,它只會顯示第一個*元素。C基本環形緩衝區問題

任何人都可以看到我失蹤的明顯錯誤。

謝謝提前。

#include "stdafx.h" 
#include <stdio.h> 
#include <string.h> 

#define BUFFER_LENGTH 8 

typedef struct circular_buffer 
{ 
    float buffer[BUFFER_LENGTH]; 
    float *buffer_end; 
    float *head; 
    float *tail; 
    size_t count; 
} circular_buffer; 

circular_buffer buffer; 

void cb_init(circular_buffer *cb) 
{ 
    memset(cb->buffer, 0, BUFFER_LENGTH * sizeof(float)); 

    cb->buffer_end = (float *)cb->buffer + BUFFER_LENGTH * sizeof(float); 
    cb->count = 0; 
    cb->head = cb->buffer; 
    cb->tail = cb->buffer; 
} 

void cb_push_back(circular_buffer *cb, float item) 
{ 
    *cb->head = item; 
    cb->head = (float *)cb->head++; 
    if (cb->head == cb->buffer_end) 
     cb->head = &cb->buffer[0]; 
    cb->count++; 
} 

float cb_pop_front(circular_buffer *cb) 
{ 
    float item = 0; 
    item = *cb->tail; 
    cb->tail = (float*)cb->tail++; 
    if (cb->tail == cb->buffer_end) 
     cb->tail = &cb->buffer[0]; 
    cb->count--; 
    return item; 
} 

float cb_peek_front(circular_buffer *cb, size_t pos) 
{ 
    float *arrPos; 
    size_t i = 0; 
    do 
    { 
     arrPos = (float*)cb->tail + i; 
     if (arrPos == cb->buffer_end) 
      arrPos = cb->buffer; 
     i++; 
    } while (i <= pos); 

    return *arrPos; 

} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    cb_init(&buffer); 

    cb_push_back(&buffer, 5); 
    printf("%f\n",cb_pop_front(&buffer)); 
    cb_push_back(&buffer, 6); 
    printf("%f\n", cb_pop_front(&buffer)); 
    cb_push_back(&buffer, 7); 
    printf("%f\n", cb_pop_front(&buffer)); 
    cb_push_back(&buffer, 8); 
    printf("%f\n", cb_pop_front(&buffer)); 
    cb_push_back(&buffer, 9); 
    printf("%f\n", cb_pop_front(&buffer)); 
    cb_push_back(&buffer, 10); 
    printf("%f\n", cb_pop_front(&buffer)); 
    cb_push_back(&buffer, 11); 
    printf("%f\n", cb_pop_front(&buffer)); 
    cb_push_back(&buffer, 12); 
    printf("%f\n", cb_pop_front(&buffer)); 

    // stops working here 
    cb_push_back(&buffer, 13); 
    printf("%f\n", cb_pop_front(&buffer)); 

    cb_push_back(&buffer, 14); 
    printf("%f\n", cb_pop_front(&buffer)); 


    return 0; 
} 
+0

你爲什麼不只是把緩衝區作爲數組和工作有指標,而不是一個指針?然後當向前推進時,索引換行說'索引=(索引+ 1)%BUFFER_LENGTH',或者當向後移動時索引=(索引+ BUFFER_LENGTH-1)%BUFFER_LENGTH'。 –

+0

您不會在輸入上檢測「緩衝區已滿」或在輸出上檢測到「緩衝區欠載」。你在那裏做的唯一的測試是「緩衝區運行」。另外,有「頭」,「尾巴」*和*「計數」有點多餘。 – tofro

+0

'cb-> head =(float *)cb-> head ++;'這裏未定義的行爲。爲什麼從浮動轉換爲浮動? – Lundin

回答

1

cb->buffer_end = (float *)cb->buffer + BUFFER_LENGTH * sizeof(float); 

不會做你期望的。

將其更改爲

cb->buffer_end = cb->buffer + BUFFER_LENGTH; 

到它指向剛剛超越到緩衝區的最後一個元素。


也只是刪除所有這些無用的轉換到(float *)


而且要通過更換

cb->head = (float *)cb->head++; 

只是一個簡單的

cb->head++; 

cb->tail = (float*)cb->tail++; 

通過

cb->tail++; 
+1

似乎足以解決OP代碼中的問題。如果downvoter發表評論,那將會很棒。 –

+0

@ManosNikolaidis,而不是我,但倒退是在答案的第一稿,然後暫時刪除。 –

+0

謝謝你的幫助,解決了這個問題。 – Jim

1

當使用指針算術時,您不恰當地考慮元素的大小。例如

bufpointer += 1; 

前進到下一個元素,就像你做數組索引,您也不必考慮每個元素的大小。所以

cb->buffer_end = (float *)cb->buffer + BUFFER_LENGTH * sizeof(float); 

成爲

cb->buffer_end = cb->buffer + BUFFER_LENGTH;