2017-01-30 63 views
0

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

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

为了测试我的阵列我创建了一个简单的测试类,它只是跟踪实例的数量而存在的话,每一次构造函数或拷贝构造函数被调用的变量调用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存在,那么它们的正确量在Array中分配,并在范围末尾销毁。相反,我得到0, 1, 1, 2, 2, 3, 3, 4, 4...的输出,这表明元素由于某种原因未被正确销毁。这就像元素只在新元素被分配时被释放,但这不是我想要的行为。此外,在for循环之外,instance_count等于100,这意味着即使没有更多的Array实例,也有剩余的对象。有人请向我解释为什么std::allocator没有正确清理元素?

+0

什么'TestObject'看起来像什么?如果你使用'std :: vector '而不是'Array ',你的输出是什么? – 1201ProgramAlarm

回答

1

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

要创建对象,请调用allocateconstruct

要销毁物体,您需要先拨打destroy,然后再拨deallocate

相关问题