• 0 Posts
  • 6 Comments
Joined 1 year ago
cake
Cake day: June 12th, 2023

help-circle


  • If you develop or debug a container, it is useful to have a special test class for the elements that covers potential container specific errors.

    struct ContainerTester {
    	static int instances;
    	int counter{};
    	int val;
    	
    	ContainerTester() : ContainerTester(0) {}
    	ContainerTester(int val) : val(val)
    	{
    		++counter;
    		++instances;
    	}
    	~ContainerTester() {
    		--counter;
    		--instances;
    		if (counter < 0) std::cout << "multiple destructor calls on same element" << std::endl;
    		if (instances < 0) std::cout << "negative number of instances" << std::endl;
    	}
    };
    
    int ContainerTester::instances{};
    
    std::ostream& operator<<(std::ostream& o, const ContainerTester& c) {return o << c.val;}
    

    If I run your code with ContainerTester instead of int, i get:

    negative number of instances
    negative number of instances
    negative number of instances
    negative number of instances
    negative number of instances
    negative number of instances
    multiple destructor calls on same element
    negative number of instances
    double free or corruption (out)
    segmentation fault
    

    So it’s more obvious that very bad things do happen :)

    Oh and note, that allocator::destroy is deprecated in C++17 and was removed with C++20.


  • That’s btw. another error. You byte-copy the elements and Call the destructor on the original ones. This will work only, if your element’s type is trivially destructible.

    Given your T has an allocating constructor and therefore an deallocating destructor:

    Creating a T Calls T::T() that allocates memory.

    Resizing your deque Calls T::~T() by .destroy(), deallocating this memory.

    Destructing your deque should destroy the elements. Thus you call the constructor once and the destructor 1+number of deque resizes.