About the Blog

Back to Scriptionary

The Scriptionary blog is part of the Scriptionary wiki. Informal news and information will be announced here.

More…

Advertisement

Popular Tags

The tag with the most posts is the largest and vice versa.

Flattening Multidimensional Arrays

11 October 2008 - 16:25, By E. Luten
Edit: Thank you, fixitman for the insightful comment; the code has been fixed to work with non-square arrays as well.

In an effort to produce a better performing multidimensional array, I would like to share the following with you. Say we have a Matrix (or multidimensional array) of 5 x 5 integer elements, M. In order to allocate such an array in C++, we use the following code:

const size_t Width = 5;
const size_t Height = 5;
int** Array = new int*[Height]; // 2-Dimensional

for (size_t i = 0; i < Height; ++i)
	Array[i] = new int[Width];

// etcetera.

for (size_t i = 0; i < Height; ++i)
	delete[] Array[i];
delete[] Array;

In order to counter-act this looping behavior, which, in many cases will slow down the program upon allocation and freeing of memory (due to the loops), the array may be flattened like so:

const size_t Width = 5;
const size_t Height = 5;
int* Array = new int[Width*Height]; // 1-Dimensional

// etcetera.

delete [] Array;

Thus causing fewer allocations than before, and eliminating loops entirely. You might think that the array is entirely out of order, and no logical index can be obtained for selecting e.g.: Array[2][3];. This is where a simple calculation comes in handy.

AX,Y = (Y x Width) + X

With this calculation we can select our element by doing the following:

[...]
// desired position:
const size_t X = 2;
const size_t Y = 3;
[...]
int RequestedInteger = Array[(Y*Width)+X];
O 0 1 2 3 4 X
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
4 20 21 22 23 24
Y

This works because if we visualize our flattened array’s indexes in a table (right →), we can see that if we take Y (3) and multiply it by the Width (5) we get the appropriate first index of the row (15, or 0,3). If we add X (2) we have selected index 17, which is the index we want (X2, Y3).

This implementation is faster because we only allocate one single block of memory of X*Y instead of X*Y blocks of memory. The disadvantage of this is that to select any index from the array, you will have to calculate the expression, but this is a minor operation compared to the allocation/de-allocation loops.

1 Comment | Tags: Tagged with:

Notice:
Scriptionary is not responsible in any way for any user-submitted comments. The comments are owned by whoever submitted them.

Comments:

  1. fixitman says;
    27 Oct 2008 - 10:29

    Actually, you should be multiplying by width, not height. Your example works because the array is square. however if:

    width = 5, and height = 4,
    x = 2, y = 3

    array[y*height+x] would return 14
    whereas array[y*width+x] would return 17, your desired result.

Add a Comment