使用std :: allocator

时间:2017-01-30 21:44:14

标签: c++ arrays stl dynamic-memory-allocation allocator

我一直在尝试编写自己的STL容器实现,但是我在释放元素时遇到了一些麻烦。我创建了一个简单的Array类,它基本上是标准C ++数组的包装器。我一直试图实现的重大改变是允许数组初始化,如果他们没有默认构造函数(我知道Vector可以做到这一点,但我想练习实现它)。由于这个功能,我不能使用new所以我决定让容器使用像标准STL容器一样的Allocator。 Array看起来有点像这样:

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...
}

为了测试我的数组,我创建了一个简单的Test类,只需跟踪存在的实例数,每次调用构造函数或复制构造函数时,名为instance_count的变量都会递增,并且每次都会增加析构函数被称为变量递减。然后我编写了以下方法来断言Array正在创建和销毁元素:

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
    }
}

我的预期输出为0, 1, 0, 2, 0, 3, 0, 4...,这意味着在范围的开头没有TestObjects存在,然后在数组中分配正确的数量,并在范围的末尾销毁它们。相反,我得到0, 1, 1, 2, 2, 3, 3, 4, 4...的输出,表明元素由于某种原因没有被正确销毁。就像元素只在分配新元素时才被释放,但这不是我想要的行为。此外,在for循环之外,instance_count等于100,这意味着即使没有Array的实例,也有剩余的对象。有人可以向我解释为什么std::allocator没有正确清理元素吗?

1 个答案:

答案 0 :(得分:2)

因为你没有破坏对象,只需释放它们占用的内存。分配器分离分配/解除分配(使用allocatedeallocate)和构造/销毁(使用constructdestroy)的概念。

要创建对象,您需要调用allocateconstruct

要销毁对象,您需要拨打destroy,然后拨打deallocate