0

After I run the code bellow, I get a runtime error "double free or corruption".

If I get rid of the destructor content (the delete) it works fine. What's wrong?

The message inside the destructor helped me to find that it is related to the destructor of the variable element, but I know really know how to fix it.

#include <stdio.h>
#include <inttypes.h>
#include <string.h>
/// First test class
class test_t {
    public:
    uint16_t *number;
    uint16_t& get_number(){return number[0];};

    test_t(){number = new uint16_t[16];};
    ~test_t(){
        printf("DESTOY test\n");
        delete [] number;
        };

    test_t& operator=(const test_t& other){
        if (this != &other) {
            memcpy( number, other.number, 16 );
        }
        return *this;
    }
};

/// Circular Buffer template
template <class CB_TYPE>
class circular_buffer_t
{
    public:
        /// Control variables
        uint32_t beg_index, end_index, size, capacity;
        CB_TYPE *data;

        /// Methods
        circular_buffer_t(){
            this->beg_index = 0;
            this->end_index = 0;
            this->size = 0;
            this->capacity = 0;

            this->data = NULL;
        };

        ~circular_buffer_t(){
            printf("DESTOY CB\n");

            if (this->data != NULL) {
                delete []data;
            }
        };

        CB_TYPE& operator[](uint32_t index){
            uint32_t position = this->beg_index + index;
                if (this->end_index >= this->capacity) position = 0;

            return data[index];
        };

        CB_TYPE operator[](uint32_t index) const {
            uint32_t position = this->beg_index + index;
                if (this->end_index >= this->capacity) position = 0;

            return data[index];
        };

        void allocate(uint32_t elements){
            this->capacity = elements;
            this->data = new CB_TYPE[this->capacity];
            if (this->data == NULL)
                printf("Could not allocate the circular buffer size.\n");
        };


        int32_t push_back(CB_TYPE new_element){
            int32_t virtual_position = -1;

            this->size++;
            memcpy(&this->data[end_index], &new_element, sizeof(CB_TYPE));

            this->end_index++;
            if (this->end_index >= this->capacity) this->end_index = 0;

            virtual_position = this->size - 1;

            return virtual_position;
        };
};


int main()
{
    circular_buffer_t<test_t> cb;
    cb.allocate(10);

    {
        test_t element;
        cb.push_back(element);
    } // This emulates the call for the destructor from "element"


    printf("done %d", cb[0].get_number() );
    return 1;
}
Marco
  • 1
  • 3
    You need to add a proper copy constructor to `test_t`. See the [Rule of Three](http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)). – Captain Obvlious Aug 31 '14 at 20:18
  • 1
    @CaptainObvlious Yup! Totally agreed: [The Rule of three (five)](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) isn't served well by this class. – πάντα ῥεῖ Aug 31 '14 at 20:25
  • 1
    Why don't use `std::unique_ptr` or `std::shared_ptr` or directly `uint16_t[16]`? – NetVipeC Aug 31 '14 at 22:56
  • Possible duplicate of [How to track down a double free or corruption error in C++ with gdb](https://stackoverflow.com/questions/2902064/how-to-track-down-a-double-free-or-corruption-error-in-c-with-gdb) – Raedwald Dec 06 '18 at 09:07

0 Answers0