5

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

如果我使用 alloc、memcpy、memset、free ins c++ 代码有什么缺点吗?如果有的话,那些是什么?

4

5 回答 5

2

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

在 C++ 中,手动内存管理几乎总是错误的。如果你真的需要一个裸数组,你至少应该使用类似boost::scoped_arrayor的包装器boost::shared_arraystd::unique_ptr也可用于管理数组。

于 2012-11-26T08:59:31.887 回答
2

Vector在两个方面增加价值:

  1. 提供数组中不存在的附加功能C,例如调整大小、检查当前大小等。您可以从其界面中找到更好的替代方案到您的自定义解决方案。
  2. 捕获一些错误,例如寻址超出vector.

如果您对专有数据管理感到满意并对代码质量充满信心,则不需要vector. 但是请注意,这可能会带来一些软件问题,例如与C数组相比降低了数组的可维护性vector(例如,未来的代码可能会访问超出范围的值,即使您当前的代码没有)。

编辑:请参阅@Als 答案以了解您的情况(std::array)的可能替代方案。

于 2012-11-26T09:02:33.257 回答
1

如果您要插入或删除许多对象,则向量有 1 个主要(相对而言)问题,除了在此处无关的向量的开头/中间插入的情况(数组具有相同的问题)。

如果您有大量的插入要完成,您通常会reserve在插入之前添加一个调用。称它为vector.reserve(<best guess number of objects to be inserted>)

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

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

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

于 2012-11-26T08:59:13.867 回答
1

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

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

数组很可能会为您提供更好的性能,因为不需要像std::vector.

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

如果我使用 alloc、memcpy、memset、free ins c++ 代码有什么缺点吗?如果有的话,那些是什么?

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

  • 使用 C++,除非无法避免,否则根本不应该使用动态分配。您应该使用智能指针。这正是 C++ 提供它们的目的。
  • 此外,手动内存管理更容易出错。由于您使用的是 C++,因此您的代码的未来维护者可能只是假设您已经使用new并调用deletemalloced 指针,从而导致了 UB。
  • 使用 c 风格函数的另一个缺点是,不像new它们不调用对象构造函数,这会使您的对象未初始化。
于 2012-11-26T09:03:48.000 回答
0

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

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

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

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

于 2012-11-26T09:21:22.873 回答