用std :: valarray替换POD C风格的数组是个坏主意吗?

时间:2015-01-30 14:13:59

标签: c++ c++11 stl valarray

我正在处理写得不好且内存泄漏很多的代码库。

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

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

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

现在我在想,我正在重新发明轮子吗?为什么不用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

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

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

3 个答案:

答案 0 :(得分:13)

C风格数组的标准替换为std::vectorstd::valarray是一些“奇怪的”数学向量,用于执行类数计算。它并不是真正设计用于存储任意对象的数组。

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

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

答案 1 :(得分:6)

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

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

除了在销毁时进行空检查之外,它还拥有int*以外的没有运行时开销。它使用的空间不会超过int*

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

我会先从std::unique_ptr<int[]>开始作为第一遍,让它运转起来。在我认为智能缓冲管理是值得的之后,我可能会将一些代码转换为std::vector<int>

实际上,作为第一次通过,我会查找memcpymemset以及类似的功能,并确保在我开始添加之前他们没有对相关结构进行操作RAII成员。

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

答案 2 :(得分:5)

我更希望std::vector替代c风格的数组。您可以通过.data()直接访问基础数据(类似裸指针):

  

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