2017-01-30 97 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

相關問題