这是一个相当学术性的问题,我意识到它在优化方面很重要,但它只是出于兴趣。
根据我的理解,当您调用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
存储了两次。这是不可避免的情况,还是有办法确保只存储一次尺寸?
答案 0 :(得分:3)
矢量通常不存储大小。通常的实现使指针保持超过最后一个元素的末尾,并且一个指针超过分配的内存的末尾,因为可以reserve
空间而不实际存储元素。但是,没有标准的方法来访问new存储的大小(可能不会存储开始),因此通常需要一些重复。
答案 1 :(得分:3)
是。但这是编译器一无所知的堆分配器的实现细节。它几乎肯定与向量的容量不同,因为向量只对元素的数量感兴趣,而不是字节数。而且,为了自己的目的,堆块往往会有额外的开销。
答案 2 :(得分:3)
std::vector
不分配内存; std::allocator
,或者你赋予vector
的任何分配器,都是分配内存的。分配器接口被赋予分配/解除分配的项目数,因此不需要实际存储它。
答案 3 :(得分:0)
你的大小在错误的地方 - 你将它与每个元素一起存储(借助于一个VectorStorage数组),它还包含一个T的数组(每个VectorStorage实例)。你真的想拥有它吗?像这样的数组里面的数组?你永远不会在你的析构函数中清理你的T数组。