当我使用new
分配多维数组时,我这样做:
void manipulateArray(unsigned nrows, unsigned ncols[])
{
typedef Fred* FredPtr;
FredPtr* matrix = new FredPtr[nrows];
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = new Fred[ ncols[i] ];
}
其中ncols[]
包含matrix
中每个元素的长度,nrows
包含matrix
中元素的数量。
如果我想填充matrix
,那么我有
for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols[i]; ++j) {
someFunction( matrix[i][j] );
但我正在阅读C++ FAQ,他说要非常小心。我应该先用NULL
初始化每一行。然后,我应trycatch
分配行。我真的不明白为什么这一切。我总是(但我在开头)使用上面的代码用C风格初始化。
常见问题要我这样做
void manipulateArray(unsigned nrows, unsigned ncols[])
{
typedef Fred* FredPtr;
FredPtr* matrix = new FredPtr[nrows];
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = NULL;
try {
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = new Fred[ ncols[i] ];
for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols[i]; ++j) {
someFunction( matrix[i][j] );
}
}
}
catch (...) {
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
throw; // Re-throw the current exception
}
}
1 /总是小心翼翼地初始化它是牵强还是非常合适?
2 /他们是否正在以这种方式进行,因为他们正在处理非内置类型?代码是否与double* matrix = new double[nrows];
相同(具有相同的谨慎程度)?
由于
编辑
部分答案在next item in FAQ
答案 0 :(得分:2)
这种小心的原因是,如果任何这些分配失败,或者Fred构造函数抛出,你将会发生内存泄漏。如果你要在callstack上面捕获异常,那么你没有处理你分配的内存,这是一个泄漏。
1)这是正确的,但一般来说,如果你要防止内存泄漏这么麻烦,你宁愿使用std::vector
和std::shared_ptr
(等等)来管理内存对你而言。
2)对于内置类型,它是相同的,但至少如果分配失败,则抛出的唯一异常是std::bad_alloc
。
答案 1 :(得分:0)
我认为这取决于目标平台和系统要求。如果安全是一个高优先级和/或如果你的内存不足,那么不,这不是牵强附会。但是,如果你不太关注安全性而且你知道系统的用户将有足够的可用内存,那么我也不会这样做。
它不依赖于是否使用内置类型。 FAQ解决方案将指向行的指针置零,以便在发生异常时,仅删除已创建的那些行(而不是某些随机内存位置)。
那就是说,我只能说第二个R. Martinho Ferndandes的评论,你应该使用STL容器。管理自己的记忆是乏味和危险的。