2011-09-30 23 views
3

這是一個頗爲學術化的問題,我認識到它在優化方面沒有什麼問題,但它只是出於興趣。矢量是否必須存儲兩次大小?

從我的理解,當你調用new[size],額外的空間分配給存儲分配的數組的大小。這是如此當調用delete []時,知道可以釋放多少空間。

我做了什麼是寫我是怎麼想的一個載體將大致實現:

#include <cstddef> 

template <class T> 
class Vector 
{ 
public: 
    struct VectorStorage 
    { 
    std::size_t size; 
    T data[]; 
    }; 

    Vector(std::size_t size) : storage(new VectorStorage[size]) 
    { 
    storage->size = size; 
    } 

    std::size_t size() 
    { 
    return storage->size; 
    } 

    ~Vector() 
    { 
    delete[] storage; 
    } 
private: 
    VectorStorage* storage; 
}; 

據我所知,size存儲兩次。一旦在VectorStorage對象直接(因爲它需要這樣size()函數可以工作),但再次以編譯器隱藏的方式,所以delete[]可以工作。

好像size存儲兩次。這種情況是不可避免的,還是有辦法確保大小隻存儲一次?

+3

你公然無視[三規則(http://stackoverflow.com/q/4172722/46642)。 –

+0

如在,賦值運算符?這只是一個例子,不是矢量的完整實現。 – Clinton

回答

3

std::vector不分配存儲器; std::allocator,或者你給vector的任何分配器,是分配內存的東西。分配器接口被賦予分配/釋放的項目數量,所以不需要實際存儲它。

+0

分配器可以避免存儲大小的方式是什麼? – Clinton

+1

@Clinton:我不確定你在問什麼。分配器可以做任何想要的事情。它可能有一個私人堆。它可以使用直接的OS調用來獲取堆塊並管理內存本身。它可以做任何想要的事情。 –

3

載體通常不存儲大小。通常的實現會保持一個指針超過最後一個元素的末尾,並且一個指針超過分配內存的末尾,因爲可以實際存儲元素的空間不會實際存儲在其中。但是,沒有標準的方式來訪問新存儲的大小(可能不會存儲到開始處),因此通常需要重複。

3

是的。但是這是堆分配器的實現細節,編譯器一無所知。它幾乎肯定與矢量的容量不同,因爲矢量只對元素數量感興趣,而不是字節數量。而且堆塊往往會爲了自己的目的而有額外的開銷。

0

你在錯誤的地方大小 - 你與每一個元素存放(憑藉VectorStorage陣列的),其中還包含(每VectorStorage的實例)T的你真的是一個數組像這樣的數組內有一個數組?你永遠不會在你的析構函數中清理你的數組。

+0

Joe:我的意思是一個帶有size_t的結構,後跟一個大小爲size的T的數組。我怎樣才能用'new'來分配? – Clinton