【问题标题】:C++: is it safe to work with std::vectors as if they were arrays?C++:像使用数组一样使用 std::vectors 是否安全?
【发布时间】:2011-05-30 08:58:47
【问题描述】:

我需要有一个固定大小的元素数组并调用它们需要知道它们如何放置在内存中的函数,特别是:

  • glVertexPointer 这样的函数,需要知道顶点在哪里,它们之间的距离等等。在我的例子中,顶点是要存储的元素的成员。

  • 1234563 x - & array[0]) -- 顺便说一句,这对我来说听起来很肮脏:这是一种好习惯还是我应该做其他事情?

为此使用std::vector 是否安全?

有些事情让我觉得std::array 更合适,但是:

  • 我的结构的构造函数和析构函数很少被调用:我不介意这样的开销。

  • 我要将std::vector 容量设置为我需要的大小(用于std::array 的大小,因此不会因零星重新分配而产生任何开销。

  • 我不介意std::vector 的内部结构需要一点空间开销。

  • 我可以使用调整向量大小的能力(或者更好:在设置过程中选择大小),我认为 std::array 无法做到这一点,因为它的大小是模板参数(太糟糕了:即使使用类似 C 的旧数组,我也可以做到这一点,只需在堆上动态分配它)。


如果 std::vector 适合我的目的,我想详细了解它是否会对 std::array(或普通 C 数组)产生一些运行时开销:

我知道一旦我增加它的大小,它就会为任何元素调用默认构造函数(但我想如果我的数据有一个空的默认构造函数,这不会花费任何成本?),析构函数也是如此。还有什么?

【问题讨论】:

  • 在调用glVertexPointer 之后最好不要调整向量的大小。除此之外,一切都会好的。
  • Convert std::vector to array 的可能重复项

标签: c++ arrays stl vector containers


【解决方案1】:

在多线程环境和动态内存分配中工作可能会导致问题,因为向量通常是连续的内存块,而指针可能不是!

【讨论】:

    【解决方案2】:

    如果你真的想要一个 std::array,你可以使用 boost::array。它就像一个普通数组,但支持迭代器,您可以轻松地将它与 STL 算法一起使用。

    【讨论】:

      【解决方案3】:

      这比在堆栈上拥有一个数组更安全:你的堆栈到底有多大?你的数组可以变成多大(固定大小,但在以后的版本中可以增加大小)?

      【讨论】:

        【解决方案4】:

        向量保证所有元素都在连续内存中,因此在您的场景中使用是安全的。与 c 样式的数组相比,性能可能会受到很小的影响,例如由于向量实现完成的索引验证。在大多数情况下,性能是由其他因素决定的,所以在实际的性能测量表明这是一个真正的问题之前,我不会担心这一点。

        正如其他人所指出的,如果您使用指向元素(或迭代器)的指针来访问它,请确保在使用存储在其中的数据时不要重新分配向量。

        【讨论】:

        • 该标准实际上并不要求将元素存储在连续的内存中。
        • @marcog:嗯,C++03 标准可以。 C++98 没有,但仍然总是如此,有关此问题的讨论,请参阅 herbsutter.com/2008/04/07/…
        • @vil 感谢您的纠正,我不知道有变化!
        • +1 In most cases, the performance is determined by something else though
        • 请阅读:stdvector-is-so-much-slower-than-plain-arrays 在这里我们展示了C-arrays和vectors之间基本上没有速度差异。
        【解决方案5】:

        是的,您可以在 OpenGL 中将其用作数组 :) 示例:

        glBufferData( GL_ARRAY_BUFFER_ARB, dataVec.size() * sizeof( dataVec[0] ), &dataVec[0], GL_STATIC_DRAW_ARB );
        

        dataVec 是 std::Vector

        【讨论】:

          【解决方案6】:

          可以将 std::vector 中的数据视为数组,用 &v[0] 获取指向它开头的指针。显然,如果你做了任何可以重新分配数据的事情,那么你的指针可能会失效。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-04
            • 1970-01-01
            • 2014-09-29
            • 2011-05-05
            • 2012-12-04
            • 1970-01-01
            相关资源
            最近更新 更多