向量是否必须存储两次大小?

时间:2011-09-30 01:43:41

标签: c++ optimization memory-management vector new-operator

这是一个相当学术性的问题,我意识到它在优化方面很重要,但它只是出于兴趣。

根据我的理解,当您调用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存储了两次。这是不可避免的情况,还是有办法确保只存储一次尺寸?

4 个答案:

答案 0 :(得分:3)

矢量通常不存储大小。通常的实现使指针保持超过最后一个元素的末尾,并且一个指针超过分配的内存的末尾,因为可以reserve空间而不实际存储元素。但是,没有标准的方法来访问new存储的大小(可能不会存储开始),因此通常需要一些重复。

答案 1 :(得分:3)

是。但这是编译器一无所知的堆分配器的实现细节。它几乎肯定与向量的容量不同,因为向量只对元素的数量感兴趣,而不是字节数。而且,为了自己的目的,堆块往往会有额外的开销。

答案 2 :(得分:3)

std::vector不分配内存; std::allocator,或者你赋予vector的任何分配器,都是分配内存的。分配器接口被赋予分配/解除分配的项目数,因此不需要实际存储它。

答案 3 :(得分:0)

你的大小在错误的地方 - 你将它与每个元素一起存储(借助于一个VectorStorage数组),它还包含一个T的数组(每个VectorStorage实例)。你真的想拥有它吗?像这样的数组里面的数组?你永远不会在你的析构函数中清理你的T数组。