我想要一个动态创建并返回二维数组的函数,或者当内存分配失败时通过异常而不会在清理已分配的行后丢失信息:
double **create (int rows, int cols)
{
double **array = new double* [rows];
for (int x=0; x<rows; x++)
{
try { array[x] = new double [cols]; }
catch (exception &e)
{
x--;
for (; x>=0; x--)
delete[] array[x]; // clean up already allocated rows
delete[] array;
throw e; // pass exception
}
for (int y=0; y<cols; y++)
array[x][y] = 0; // initialize array
}
return array;
}
所以我可以肯定,如果创建抛出,没有内存泄漏。但是我可以确定,传递的异常 e 与 new 直接抛出而不被捕获是“相同的”吗?
例如
int main ()
{
double **d;
try { d = create (HUGE_x, HUGE_y); }
catch (exception &e)
{
// 1. e could be thrown by new double* [rows]
// e.g. if HUGE_x is already to huge
// 2. e could be thrown by throw e
// e.g. if after some rows no memory anymore
// in both cases: is e the same?
}
return 0;
}
还是必须要catch (bad_alloc &e)
在create
函数里面?或者它只适用于catch (...) { /* do clean-up*/ throw; }
?是否存在与 C# 中相同的问题,即当重新抛出throw;
不简单时丢失堆栈跟踪?
还有一个更普遍的问题:
void f () { throw Object(); } // or throw "help";
void main ()
{
try { f(); }
catch (Object &e) // or catch (char *)
{
// Where is the Object or C-String created on the stack in function f()
// since we aren't any more in function f() but we are dealing with
// references/pointers to a non-existent stack?
}
}