2011-09-30 39 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