【问题标题】:Can a vector of a "fixed" size also have a false size (compared to memory size) in c++在 C++ 中,“固定”大小的向量是否也可以具有错误大小(与内存大小相比)
【发布时间】:2019-09-14 14:15:18
【问题描述】:

我知道出于优化原因,向量的大小可能不是内存中对象的实际大小。 例如,有时如果我使用push_backresize,内存中的向量实际上会保持两倍的元素数量。

我了解到,如果我从向量中推送或弹出元素,或者使用调整大小,就会出现这种情况,即使 shrink_to_fit 并不总是将向量设为所需大小。

如果我不使用所有这些方法是否相同?我只是初始化一个“固定”数量元素的向量,从不使用它们。 我可以假设如果我初始化一个大小为 16 的向量,它会在内存中以 16 * 大小的元素出现吗?

谢谢。

编辑:

我需要该向量用于其他用途。主要问题是我需要使用特定数量的内存。我可以使用数组,但会不太方便。我试图将一行的实现理解为:

std::vector<X> myVec(16);

正如我所说,我读到如果我使用推送和弹出或调整大小,操作系统(我认为)可以分配比我指定的空间更多的空间。 但是在我写的一行中,我找不到任何与此相关的内容。

谢谢你 2 :)

编辑 2:

有趣的发现:

{ 
vector<int> a(16);
vector<int> b(32);
vector<int> c(32);

cout << a.capacity(); // prints 16
cout << b.capacity(); // prints 32

b = a;  // uses vector copy "="
cout << b.capacity(); // prints 32 (!!)


cout << c.capacity(); // prints 32
c = vector<int>(16)  // uses vector move "="
cout << c.capacity(); // prints 16 (!!)}

在阅读了向量中移动和复制构造函数的实现后,我尝试了这个。

所以看起来当使用右值(即移动构造函数)时,它分配了指定的大小。但是,当使用复制赋值(或使用复制构造函数)时,它不会释放内存,并且向量的容量仍然是 32。

【问题讨论】:

  • 您能否在edit 的问题中包含一个示例,说明初始化“固定”数量元素的向量 的含义?
  • 如果你不需要push_back,...你为什么不使用std::array?
  • @1201ProgramAlarm 我想她在问向量的大小是否是元素的实际数量。理论上,他们认为在O(1) 保持插入和删除摊销复杂性是原来的两倍
  • FWIW 您可以使用capacity() 来验证已分配了多少。
  • 我不认为标准对向量的容量施加任何限制,除了它必须是&gt;= 的大小。这意味着答案将是特定于实现的,并且可能会在没有警告的情况下进行更改。

标签: c++ vector


【解决方案1】:

标准不谈论初始capacity,当使用您使用的构造函数构造时,也不用于任何其他构造函数:

26.3.11.2 向量构造函数、复制和赋值[vector.cons]

显式向量(size_type n, const Allocator& = Allocator()); 效果:构造一个带有 n 个默认插入元素的向量,使用 指定的分配器。要求:T 应为 DefaultInsertable into *这。复杂性:n 中的线性。

也就是说,结果取决于实现(因此请检查您的编译器)。

另一方面,您提到的任何功能都不能保证 capacity 的更改如您所愿/期望。

【讨论】:

    【解决方案2】:

    您似乎正在寻找boost::static_vector。它以固定容量初始化,并且在允许推送和弹出元素时永远不会超过它。一种boost::array,但跟踪存储的项目数量。

    【讨论】:

      【解决方案3】:

      这就是.reserve() 的用途。即使您还没有完全使用它,它也会根据您的要求设置容量。如果您尝试 push_back 过去,您仍然会得到重新分配。

      或者,在开始时正好创建 16 个元素,并在需要时使用尽可能多的元素。尽管没有标准保证(向量不是为担心 16 字节内存的人设计的),但没有理由让实现预先分配超过该空间,而且我不知道有任何这样做。

      【讨论】:

      • "reserve() 之后,如果发生重新分配,则 capacity() 大于或等于 reserve 的参数;否则等于 capacity() 的先前值。容量仍可能大于储备的预期容量
      • 只是想引用标准。反正现在谁在乎 16 字节 ;)
      猜你喜欢
      • 2011-02-28
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 2011-04-07
      相关资源
      最近更新 更多