如果我使用Array而不是Vector,有什么缺点吗?

时间:2012-11-26 08:54:48

标签: c++ c memory

我用C ++编写了一个MPC控制器,其中包含一个Matrix类,我将数据存储在一个数组中,并使用了C存储器函数(memcpy,memset等)。今天我用c ++ vector替换了数组,我用copy来移动内存等......我遇到了一个问题,用vector替换数组,控制信号的计算时间几乎翻了一倍。

如果我使用alloc,memcpy,memset,free ins c ++代码,是否有任何缺点?如果有什么?

5 个答案:

答案 0 :(得分:2)

使用手动内存管理意味着您还有更多工作要做。因此,您有更多机会犯错误。

C ++中的手动内存管理几乎总是错误的。如果你真的需要一个裸阵列,你至少应该使用像boost::scoped_arrayboost::shared_array这样的包装器。此外,std::unique_ptr可用于管理数组。

答案 1 :(得分:2)

Vector在两个方面增加了价值:

  1. 提供C数组中不存在的其他功能,例如调整大小,检查当前大小等。您可以从其接口到自定义解决方案找到更好的替代方案。
  2. 捕获一些错误,例如解决超出vector范围的地址。
  3. 如果您对专有数据管理感到满意并对代码质量充满信心,则不需要vector。但是请注意,这可能会带来一些软件问题,例如C数组与vector相比可维护性降低(例如,即使您当前的代码没有,未来的代码也可能会访问越界值)。

    修改: 有关您的案例中可能的替代方案,请参阅@Als答案(std::array)。

答案 2 :(得分:1)

如果要插入或删除多个对象,Vector会有一个主要(相对来说)的问题,除了插入向量的开头/中间的情况,这里不相关(数组有相同的问题)。

如果要完成大量插入操作,通常会在插入之前添加对 reserve 的调用。将其称为vector.reserve(<best guess number of objects to be inserted>)

这是因为,正如您所知,vector会根据需要分配内存。如果您一次插入大量项目,可能会涉及大量重新分配/副本,这可能会消耗大量时间。

此问题有其他解决方案。一种是使用 std::deque ,这种情况下效率稍高一些,因为它不会每次都复制整个矢量。或者使用 std::array ,它是C数组周围的矢量样式包装。

编辑:标题已更改,但此信息可能仍然有用..

答案 3 :(得分:1)

如果您已经在编译时知道数组的大小,那么使用数组,实际上std::array是更好的选择,但如果您需要动态数组,最好使用std::vector

  

如果我使用的是Array而不是Vector,有没有缺点?

数组很可能会为您提供更好的性能,因为在std::vector的情况下不需要额外的间接。

但是,请注意,在大多数情况下,性能优势在大多数情况下并不显着,除非您的探查器指出这是一个问题。

  

如果我使用alloc,memcpy,memset,free ins c ++代码,有什么缺点吗?如果有什么?

你绝对不应该在C ++中使用c风格的内存分配和管理功能。缺点是:

  • 使用C ++,你根本不应该使用动态分配,除非它们无法避免。你应该使用智能指针。这是C ++提供它们的目的。
  • 此外,手动内存管理更容易出错。由于您正在使用C ++未来的代码维护者可能只是假设您已使用new并在delete ed指针上调用malloc,从而导致UB。
  • 使用c风格函数的另一个缺点是,与new不同,它们不会调用对象构造函数,这会使对象保持未初始化状态。

答案 4 :(得分:0)

std :: vector和raw数组之间要注意的一个区别是std :: vector在复制时会调用元素的复制构造函数和复制赋值运算符,而对于原始数组,你必须自己这样做(例如像“memcpy”这样的函数不会调用复制构造函数/赋值运算符。

如果数组的元素是原始类型或POD类型(POD类型,Plain Old Data,基本上是只有公共数据成员且没有基类的类或结构),那就没关系。

这种差异正是您使用原始数组获得更好性能的原因:进行的复制较少。 C ++ 11使用右值引用和移动构造函数/赋值运算符来最小化此问题,但它仍然不可能击败手动处理的内存。

但是直接在代码中的任何地方处理内存都是一个坏主意:它可能导致内存泄漏,非异常安全的代码,并使代码过于冗长和复杂。您可以创建专门为POD类型设计的数组类,这样您就可以获得数组类的便利性和安全性,如std :: vector和原始数组的效率。