vector::size() 如何在常数时间内返回向量的大小?
Posted
技术标签:
【中文标题】vector::size() 如何在常数时间内返回向量的大小?【英文标题】:How does the vector::size() returns size of the vector in constant time? 【发布时间】:2019-01-30 08:37:16 【问题描述】:我正在浏览这个C++ Reference 并发现使用vector::size() 会在恒定时间内返回向量的大小。但是,我想知道如何在不实际遍历向量的情况下获得大小。
【问题讨论】:
如何通过遍历向量得到大小?你需要知道大小才能知道在哪里停止遍历 潜在相关问题:C++ sizeof Vector is 24?. 大小存储在成员变量中。 @Shawn 不一定。 【参考方案1】:它只记录元素的数量。
如果发生变化,则更新该数字。例如,当调用push_back
或emplace_back
时,元素的数量会增加1。这是std::vector
本质上不是线程安全的众多原因之一。
正如您所想象的,这使得std::vector
的实现非常繁琐——其他 C++ 标准库容器也是如此——这是不尝试自己编写容器类的一个很好的理由。
【讨论】:
如果我们只用向量的容量除以第一个元素的大小就可以直接得到元素个数,为什么还要为元素个数保留另一个变量? 我实际上并没有这么说 - 你知道我是一只细心的猫! @HimanshuKumar 容量和大小对于std::vector
是不同的。您不希望每次添加元素时都增加容量(因为它涉及重新分配内部数组和复制/移动所有元素),因此您甚至可以将 容量 增加大块(通常是指数级)如果你只有一个元素太短。
@HimanshuKumar size
和 capacity
是两个不同的东西,其中size <= capacity
。 capacity
是当前分配的内存可以容纳的最大元素数。 size
是在当前分配的内存中有效的实际元素的数量。当新的size
超过当前的capacity
时,内存会在插入期间重新分配。【参考方案2】:
要理解这一点,您需要了解矢量的工作原理。
一个好的心智模型是:
class vector
T *data;. // Pointer to the first element
size_t size; // Number of elements in use
size_t capacity; // Number of elements available
;
每当添加一个元素时:
元素被构造 大小增加当容量不够时,我们应该增加数据。简而言之,如果你看一下 push_back 的代码,它会是这样的:
T& push_back(T const& t)
if (size == capacity)
grow();
constructAtEnd(t);
++ size;
return back();
在实践中,由于异常保证,它有点复杂。但是,鉴于上述情况,您应该能够检查向量的实现并识别所有方法的情况。
【讨论】:
“大多数实现”存储data+size
和 data+capacity
而不是大小和容量(但这不会影响心智模型)。
@MarcGlisse:也许,但请注意 all 必须使用 std::vector<>::size_type
作为元素计数的类型。回答者的本意并非如此深入。我确定。投赞成票!
@Marc MSVC 绝对不会。 Libc++ 基于 3 个指针做类似的事情
@Marc 类型特征确实让事情变得更复杂,如果你不使用自定义分配器,我倾向于忽略它们
我个人会放弃“(大多数实现甚至以这种方式实现)” - 它破坏了答案。【参考方案3】:
std::vector
是 STL 中的一个序列容器,它有一个变量,每次都会计算元素的数量。当我们push_back()
到std::vector
的任何元素时,该变量递增,当我们从std::vector
中的pop_back()
元素时,该变量递减。
所以我认为它是这样工作的
所以 std::vector::size() 返回那个变量的大小
【讨论】:
以上是关于vector::size() 如何在常数时间内返回向量的大小?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::vector max_size() 函数会返回 -1?
关于vector.size()和string.length() 的返回类型 size_type