How do I implement a circular list (ring buffer) in C?

后端 未结 8 1586
心在旅途
心在旅途 2020-12-02 08:40

How do I implement a circular list that overwrites the oldest entry when it\'s full?

For a little background, I want to use a circular list within GWT; so using a 3

相关标签:
8条回答
  • 2020-12-02 09:21

    If you want a fixed length circular list. You can use a (dynamic) array. Use two variables for houskeeping. One for the position of the next element, one to count the number of elements.

    Put: put element on free place. move the position (modulo length). Add 1 to the count unless count equals the lengtht of the list. Get: only if count>0. move the position to the left (modulo length). Decrement the count.

    0 讨论(0)
  • 2020-12-02 09:21

    Here is a simple template solution for a circular buffer (FIFO). It does leave one storage space empty, but I think this is a small penalty for the performance and simplicity. I included a simple stress-test.

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class E: public std::exception {
    
        const char *_msg;
        E(){}; //no default constructor
    
    public:
    
        explicit E(const char *msg) throw(): _msg(msg) {};
        const char * what() const throw() {return(_msg);};
    
    };
    
    const int min_size = 2;
    const int max_size = 1000;
    
    template<typename T>
    class Fifo{
    
        int _head;
        int _tail;
        int _size;
    
        T* _storage;
    
    public:
    
        explicit Fifo(int size = min_size);
        ~Fifo(){ delete [] _storage;};
    
        bool is_full() const{
            return(((_head+1)%_size) == _tail);
        };
        bool is_empty() const{
            return(_head == _tail);
        };
    
        void add_item(const T& item);
        const T& get_item();
    
    };
    
    template<typename T>
    Fifo<T>::Fifo(int size): _size(size){
        
        if (size < min_size) throw E("Cannot create Fifo less than 2\n");
    
        _head = _tail = 0;
    
        try{
    
            _storage = new T[_size];
        }
        catch (std::bad_alloc &ba)
        {
            char e_string[500];
            sprintf(e_string, "Cannot allocate memory (%s)\n", ba.what());
            throw E(e_string);
        }
    
        printf("Constructing Fifo of size %d\n", _size);
    
    }
    
    template <typename T>
    void Fifo<T>::add_item(const T& item)
    {
        if (this->is_full()) throw E("Fifo is full.\n");
    
        _storage[_head] = item;
    
        _head = (_head + 1)%_size;
    }
    
    template <typename T>
    const T& Fifo<T>::get_item()
    {
        if (this->is_empty()) throw E("Fifo is empty.\n");
    
        int temp = _tail; //save the current tail
    
        _tail = (_tail+1)%_size; //update tail
    
        return(_storage[temp]);
    }
    
    int main()
    {
        Fifo<int> my_fifo(3);
    
        for (int i = 1, item; i < 50; i++)
        {
            my_fifo.add_item(i);
            my_fifo.add_item(i*10);
            item = my_fifo.get_item();
            printf("Item: %d\n", item);
            item = my_fifo.get_item();
            printf("Item: %d\n", item);
        }
    
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题