6

我正在使用一个写得不好并且有很多内存泄漏的代码库。

它使用了很多包含原始指针的结构,主要用作动态数组。

尽管结构通常在函数之间传递,但这些指针的分配和释放是随机放置的,不容易跟踪/推理/理解。

我将其中一些更改为类,并且这些指针将由类本身进行 RAIIed。它们运行良好并且看起来并不难看,只是我禁止复制构造和复制分配这些类只是因为我不想花时间实现它们。

现在我在想,我是在重新发明轮子吗?为什么不用 std:array 或 std::valarray 替换 C 样式的数组?

我更喜欢 std::valarray 因为它使用堆内存和 RAIIed。并且 std::array 在我的开发环境中(还)不可用。

Edit1:std::array 的另一个优点是这些动态数组中的大多数是 POD(主要是 int16_t、int32_t 和 float)数组,并且数字 API 可以使生活更轻松。

在开始之前,我有什么需要注意的吗?

我能想到的一个可能是没有一种简单的方法可以将 std::valarray 或 std::array 转换回 C 样式数组,并且我们的部分代码确实使用了指针算法并且需要将数据呈现为纯 C样式数组。

还要别的吗?

编辑 2

我最近遇到了这个问题。一个非常糟糕的事情std::valarray是它在 C++11 之前不能安全地复制分配。

正如该答案中所引用的,在 C++03 及更早版本中,如果源和目标的大小不同,则为 UB。

4

3 回答 3

13

C 样式数组的标准替换是std::vector. std::valarray是一些“奇怪”的数学向量,用于进行类似数字计算的事情。它并不是真正设计用于存储任意对象的数组。

话虽如此,使用std::vector很可能是一个非常 好的主意。它将修复您的泄漏、使用堆、可调整大小、具有出色的异常安全性等等。

它还保证数据存储在一个连续的内存块中。您可以使用成员函数获取指向所述块的指针,data()或者,如果您是 C++11 之前的版本,则可以&v[0]使用非空向量v。然后,您可以像往常一样使用它进行指针业务。

于 2015-01-30T14:27:01.473 回答
6

std::unique_ptr<int[]>接近于替代拥有int*。它有一个很好的属性,它不会隐式复制自己,但会隐式移动。

复制操作将产生编译时错误,而不是运行时效率低下。

int*除了销毁时的空检查之外,它还几乎没有运行时开销。它使用的空间不超过int*.

std::vector<int>存储 3 个指针和隐式副本(这可能很昂贵,并且与您现有的代码行为不匹配)。

我会从std::unique_ptr<int[]>第一遍开始并让它工作。std::vector<int>在我决定智能缓冲区管理是值得的之后,我可能会转换一些代码。

实际上,作为第一遍,在我开始添加 RAII 成员之前,我会寻找memcpymemset类似的功能,并确保它们不在相关结构上运行。

Astd::unique_ptr<int[]>表示默认为结构创建的析构函数将为您执行 RAII 清理,而无需编写任何新代码。

于 2015-01-30T14:55:45.693 回答
5

我更喜欢std::vector替换 c 样式的数组。您可以通过以下方式直接访问底层数据(类似于裸指针).data()

返回指向用作元素存储的基础数组的指针。

于 2015-01-30T14:27:09.567 回答