向量是否必须存储两次大小?
这是一个相当学术的问题,我意识到这对于优化来说无关紧要,但这只是出于兴趣。
据我了解,当您调用 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() 函数才能工作),但编译器再次以隐藏方式,因此删除[] 可以工作。
看起来 size
被存储了两次。这种情况是不可避免的吗,还是有办法保证尺寸只存储一次?
This is a rather academic question, I realise it matters little regarding optimization, but it is just out of interest.
From what I understand, when you call new[size]
, additional space is allocated to store the size of the allocated array. This is so when delete []
is called, it is known how much space can be freed.
What I've done is written how I think a vector would roughly be implemented:
#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;
};
As far as I can tell, size
is stored twice. Once in the VectorStorage
object directly (as it needs to be so the size()
function can work) but again in a hidden way by the compiler, so delete[]
can work.
It seems like size
is stored twice. Is this the case and unavoidable, or is there a way to ensure that the size is only stored once?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
std::vector
不分配内存;std::allocator
或您为vector
提供的任何分配器,是分配内存的。分配器接口给出了要分配/释放的项目数,因此不需要实际存储它。std::vector
does not allocate memory;std::allocator
, or whatever allocator you give thevector
, is what allocates the memory. The allocator interface is given the number of items to allocate/deallocate, so it is not required to actually store that.向量通常不存储大小。通常的实现将指针保留在最后一个元素的末尾,并将指针保留在分配的内存的末尾,因为人们可以保留空间而不实际在其中存储元素。然而,没有标准的方法来访问 new 存储的大小(可能一开始就没有存储),因此通常需要一些复制。
Vectors don't usually store the size. The usual implementation keeps a pointer past the end of the last element and one past the end of the allocated memory, since one can
reserve
space without actually storing elements in it. However, there is no standard way to access the size stored by new (which may not be stored to begin with), so some duplication is usually needed.是的。但这是编译器一无所知的堆分配器的实现细节。它几乎肯定与向量的容量不同,因为向量只对元素的数量感兴趣,而不是字节的数量。而且堆块出于其自身目的往往会产生额外的开销。
Yes. But that's an implementation detail of the heap allocator that the compiler knows nothing about. It is almost certainly not the same as the capacity of the vector since the vector is only interested in the number of elements, not the number of bytes. And a heap block tends to have extra overhead for its own purposes.
您的大小放在错误的位置 - 您将其与每个元素一起存储(通过 VectorStorage 数组),其中还包含 T 的数组(每个 VectorStorage 实例)。您真的打算在里面有一个数组吗像这样的数组?您也永远不会在析构函数中清理 T 数组。
You have size in the wrong place -- you're storing it with every element (by virtue of an array of VectorStorage), which also contains an array (per instance of VectorStorage) of T. Do you really mean to have an array inside an array like that? You're never cleaning up your array of T in your destructor either.