Hi I\'m pretty new to C++ and I need to dynamicacally allocate two-dimensional array. No error but in runtime when I set a order and first row then I get a runtime error: \"
You forgot to increment arr
in your initialization loop:
for(int i = 0;i < order; i++){
*arr = new double[order+1];
Do this instead:
for(int i = 0;i < order; i++){
arr[i] = new double[order+1];
Also, unless your going to change the dimensions of one of the rows, the method above is inefficient compared to this way of allocating a 2 dimensional array:
double ** allocateDynamicArray(int &order){
double ** arr = new double *[order];
int cols = order+1;
double *pool = new double [order * cols];
for(int i = 0;i < order; i++, pool += cols){
arr[i] = pool;
}
return arr;
}
void deallocateDynamicArray(double **arr){
delete [] arr[0];
delete [] arr;
}
Just two calls to new[]
and only two calls to delete[]
are needed, regardless of the number of rows and columns.
The other reason why the second form above should be favored over the first form is in the case where new[]
may throw an exception.
Using the first form, if somewhere in that loop, new[]
throws an exception, you have to keep track of all of the previous successful allocations, and "roll them back" by issuing delete[]
calls. Not nice.
Using the second form, if the first call to new[]
fails, then there is no harm as the exception will be thrown without leakage (since no memory was successfully allocated). If the second call to new[]
fails, all you need to do is to provide (inside of a catch
block) the deletion of the first call to new[]
.
double ** allocateDynamicArray(int &order) {
double ** arr = new double *[order];
int cols = order+1;
try {
double *pool = new double [order * cols];
}
catch (std::bad_alloc& e)
{
delete [] arr; // delete previous allocation
return nullptr; // or rethrow the exception here
}
for(int i = 0;i < order; i++, pool += cols)
arr[i] = pool;
return arr;
}
Note that std::vector
does all of this work for you. However if for some reason you can't use vector, and the two dimensional array will remain the same size throughout its lifetime, use the second form.
In addition, the second method lessens memory fragmentation of the heap. Instead of rows
calls to the allocator, only one call is made to the allocator to allocate the data. If rows
were, say 1,000 or 10,000, you see right away it is better to make 2 calls to new[]
instead of 10,000 calls to new[]
.