【问题标题】:vector and dumping矢量和倾倒
【发布时间】:2009-01-28 20:15:16
【问题描述】:

据我所知,向量保证是连续的,我可以向它写入一大块内存并用它发送 fwrite。我需要做的就是确保我调用 .resize() 来强制它成为我需要的最小长度,然后我可以将它用作普通的 char 数组?这段代码是否正确

v.resize(numOfElements);
v.clear(); //so i wont get numOfElements + len when i push back
vector<char>v2;
v2.resize(numOfElements*SizeOfType);
while(...)
{
...
v.push_bacK(x); 
}
compress(&v2[0], len, &v[0], len);
fwrite(&v2[0], ....)

注意我从不推回或弹出 v2,我只调整一次大小并将其用作 char 数组。这会安全吗?如果我也倾倒了 v 那也是安全的(我确实推回并清除,我可能会倾倒它进行测试)

【问题讨论】:

  • 如果我记得,std::vector::resize 接受元素的数量,而不是字节的数量。
  • “压缩”有什么作用?
  • @strager - v2 是一个向量,所以(元素数)==(字节数)。

标签: c++ vector


【解决方案1】:
v.resize(numOfElements);
v.clear(); //so i wont get numOfElements + len when i push back

好吧,上面的代码 sn-p 实际上是分配和创建元素,只是为了再次销毁它们。它实际上与以下内容相同:

v.reserve(numOfElements);

只是这段代码要快得多。所以,v.size() == 0 在这两种情况下和v.capacity() 可能与numOfElements 在这两种情况下相同(尽管这不能保证)。然而,在第二种情况下,容量至少为 numOfElements,这意味着在您将这么多元素推送到向量之前,不会重新分配内部缓冲区。请注意,在这两种情况下,如果您尝试访问任何元素,它都是无效 - 因为实际上包含零个元素。

除此之外,我还没有在您的代码中发现问题。它是安全的,我会鼓励它使用它而不是原始的newmalloc,因为它提供了额外的安全性。但是,我不确定您所说的“转储 v”是什么意思。

【讨论】:

  • 实际上,如果我用保留替换调整大小,我的代码会崩溃,即使保留和调整大小的容量相同。我试过v2。它在 &v2[0] 上崩溃,我也尝试了 (Bytef*)(&v2.begin()),我得到向量下标超出范围。为什么破坏速度慢? AFAIK 它只是将内部计数器设置为 0
  • .clear() 将使 .size() == 0。这意味着您不能索引任何元素,因为没有。但是在这种情况下,您也可以执行 .reserve(N) ,这实际上是相同的。请注意,我不确定 .clear() 真的不会触及 .capacity()
  • 通常不会(如您的情况)。但是我现在已经在标准中查找了它以完全确定,并且对此没有任何保证
  • 感谢 jwfearn 为其添加了清晰度。这个保留/调整大小的东西似乎很混乱。我经常看到应该使用 .resize 时使用 .reserve,而且我对 .resize 对 .capacity 的作用也有疑问 :) 希望我们现在清楚
  • acidzombie24,等等。你当然应该只用 v 做储备。 v2 应该调整大小(或者在创建时已经使用长度作为构造函数参数将其放入该长度),因为您实际上希望向量具有您告诉它从一开始就具有的特定大小
【解决方案2】:

确实,std::vector 保证是连续的,以便与 C 数组布局兼容。但是,您必须知道向量的许多操作会使指向其元素的所有指针无效,因此您最好坚持一种使用方式:避免在向量上混合指针算术和方法调用。

除此之外是完全正确的,除了第一行:你想要的是

v.reserve(numOfElements);

这将分配足够的空间来将numOfElements 存储到向量中,而

v.resize(numOfElements);

将执行以下操作:

// pseudo-code
if (v.size() < numOfElements)
    insert (numOfElements - size) elements default 
    constructed at the end of the vector

if (v.size() > numOfElements)
    erase the last elements so that size = numOfElements

总而言之,在reserve 之后,您确定向量 容量 优于或等于 numOfElements,在 resize 之后,您确定向量 size 等于 numOfElements。

【讨论】:

    【解决方案3】:

    对于这样的事情,我个人会使用像 STLSoft 的 auto_buffer&lt;&gt; 这样的类:

    作为免责声明 - 我没有使用实际的 STLSoft 库版本,我改编了自己的模板,非常相似 - 我从 Matthew Wilson(STLSoft 作者)的书 "Imperfect C++" 开始。

    当我真的只想要一个普通的 C 数组时,我发现它很有用,但大小在运行时必须是动态的。 auto_buffer&lt;&gt; 比普通的旧数组更安全,但是一旦你构建了它,你就不用担心那里有多少元素 - 它总是你用什么构建它,就像一个数组一样(所以它不那么复杂比vector&lt;&gt; - 有时是合适的)。

    auto_buffer&lt;&gt; 的主要缺点是它不是标准的并且不在 Boost 中,因此您必须将一些 STLSoft 合并到您的项目中或推出您自己的版本。

    【讨论】:

    • @Zenikoder: auto_buffer&lt;&gt; 不是 STL 的一部分。
    【解决方案4】:

    是的,您使用 char 向量作为读取原始输入的缓冲区。

    // dynamically allocates a buffer of 10,000 char as buffer
    std::vector<char>   data(10000);
    
    fread(&data[0], sizeof(char),data.size(),fp);
    

    我不会用它直接将任何非 POD 数据类型读入向量中。

    您可能会使用向量作为写入源。
    但我会非常小心你如何读回它(序列化它可能更容易)。

    fwrite(&data[0], sizeof(char),data.size(),fp);
    

    【讨论】:

      【解决方案5】:

      你用resize替换reserve(),你也可以替换

      vector<char> v2
      

      vector<Type> v2
      

      这应该会稍微简化代码。

      坦率地说,这是我见过的最奇怪的向量用法,但它可能会起作用。您确定不想使用 new char[size] 和 boost 中的某种自动指针吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-05
        • 1970-01-01
        • 2019-08-02
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 2012-04-14
        • 1970-01-01
        相关资源
        最近更新 更多