作者:fjkfjaslfjsal_577 | 来源:互联网 | 2023-05-24 11:43
我正在使用编写得很糟糕的代码库并且有很多内存泄漏.
它使用了许多包含原始指针的结构,这些结构主要用作动态数组.
尽管结构通常在函数之间传递,但是这些指针的分配和释放被放置在随机位置,并且不容易被跟踪/推理/理解.
我将其中的一些更改为类,并将这些指针改为由类本身进行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
我最近遇到了这个问题.一个非常糟糕的事情std::valarray
是它在C++ 11之前不能安全地复制 - 可分配.
正如在该答案中引用的那样,在C++ 03及更早版本中,如果源和目标具有不同的大小,则为UB.
1> Baum mit Aug..:
C风格阵列的标准替代品将是std::vector
.std::valarray
是一些"奇怪的"数学向量,用于进行数字计算之类的东西.它并不是真正设计用于存储任意对象的数组.
如此说来,用std::vector
是最有可能的一个非常 不错的主意.它可以修复你的泄漏,使用堆,可调整大小,具有很大的异常安全性等等.
它还保证数据存储在一个连续的内存块中.您可以使用data()
成员函数获取指向所述块的指针,或者,如果您是C++之前的11,则使用&v[0]
非空向量v
.然后,您可以像往常一样使用它进行指针业务.
@ user3528438不复制(几乎)总是比复制快,但如果你必须*复制,使用`std :: vector`中高度优化的实现就派上用场了.
2> Yakk - Adam ..:
std::unique_ptr
是接近替代的拥有者int*
.它有一个很好的属性,它不会隐式复制自己,但它会隐式移动.
复制操作将生成编译时错误,而不是运行时效率低下.
int*
除了在销毁时进行空检查之外,它还具有除了拥有之外的任何运行时开销.它不使用空间int*
.
std::vector
存储3个指针并隐式复制(这可能很昂贵,并且与您现有的代码行为不匹配).
我会从std::unique_ptr
第一关开始,让它工作.std::vector
在我决定智能缓冲管理是值得的之后,我可能会将一些代码转换为.
其实,第一遍,我会寻找memcpy
和memset
以及类似功能,并确保有问题,他们没有在结构工作开始之前,我将RAII成员.
A std::unique_ptr
表示结构的默认创建析构函数将为您执行RAII清理,而无需编写任何新代码.
@ user3528438是的.`memset`要清除,'memcpy`要复制等等 - 所有这些都是C风格代码中常见的微优化,并且会对RAII类(在实践中)和未定义的行为(理论上)造成致命的破坏.
3> masoud..:
我更喜欢std::vector
作为c风格数组的替代品.您可以通过以下方式直接访问基础数据(类似裸指针).data()
:
返回指向用作元素存储的基础数组的指针.