简体   繁体   中英

Deallocating with std::allocator

I've been trying to write my own implementation of STL's containers for practice and I'm having some trouble deallocating my elements. I've created a simple Array class which is basically a wrapper for the standard C++ array. The big change I've been trying to implement is allowing the arrays to be initialized if they don't have a default constructor (I know Vectors can do this but I wanted to practice implementing it). Because of this feature, I can't use new so I have decided to have the container use an Allocator like the standard STL containers. The Array looks a little like this:

template<class T, class A = std::allocator<T>> class Array {
    public:
        // STL definitions and iterators...

        /// initializes an array of size elements with all elements being
        /// default constructed.
        Array(const size_type &size) : Array(size, T()) {

        }

        /// Initializes an array of size elements with all elements being
        /// copies of the fill element.
        Array(const size_type &size, const T &fill) {
             this->allocator = A(); // Get allocator from template
             this->size = this->max_size = size;

             // Allocate data array and copy the fill element into each
             // index of the array.
             this->data = this->allocator.allocate(size);
             this->allocator.construct(this->data, fill);
        }

       /// Deletes the array and all of its elements.
       ~Array() {
             // deallocate using the allocator
             this->allocator.deallocate(this->data, this->size);
       }

       // other things...
}

To test my Array I created a simple Test class which simply keeps track of the number of instances which exist of it, every time a constructor or copy constructor is called a variable called instance_count is incremented, and every time a destructor is called the variable is decremented. I then wrote the following method to assert that the Array was properly creating and destroying elements:

void testArray() {
    for (int i = 1; i < 100; i++) {
        std::cout << TestObject::instance_count << ", "; // should always == 0
        Array<TestObject> testArray(i); // Create array of I elements
        std::cout << TestObject::instance_count << ", "; // should == i
    }
}

My expected output is 0, 1, 0, 2, 0, 3, 0, 4... which means that at the beginning of the scope no TestObjects exist, then the correct amount of them are allocated in the Array and they are destroyed at the end of the scope. Instead I get the output of 0, 1, 1, 2, 2, 3, 3, 4, 4... , which indicates that elements are not being destroyed correctly for some reason. It's like the elements are only deallocated when new elements are allocated, but that is not the behavior I want. Furthermore, outside of the for loop, the instance_count is equal to 100 which means that there are objects which are leftover even after there are no more instances of Array . Can someone please explain to me why std::allocator is not cleaning up the elements correctly?

Because you're not destroying the objects, just freeing the memory that they occupy. The allocator separates the concepts of allocation/deallocation (using allocate and deallocate ) and construction/destruction (using construct and destroy ).

To create the objects, you are calling allocate and construct .

To destroy the objects, you need to call destroy and then deallocate .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM