Hi,

I'm working on some coding and ran into the problem that my multidimensional arrays are too large for my RAM. After reading a lot of articles, I figure that what I need to do is dynamically allocate the size of the array?

The array that I need to do this to is:

double array[115][4][114][114];

I have three questions:
1) Am I correct in assuming that dynamic allocation will fix my problem?
2) Would it be better if I changed my array into a vector?
3) Could someone please give an example of how I could fix my problem?

Thanks so much.

That totals to 5,978,160 bytes (assuming 8-byte double). Not horrible, but something to think about, especially if you can devise a way to avoid keeping all of those values in memory if you don't really need them.

Now to answer your question:

  1. Yes.
  2. God yes. Doing this manually is uber painful.
  3. Read the following at your own risk:

    #include <vector>
    
    using namespace std;
    
    typedef vector<double> vec1d;
    typedef vector<vec1d> vec2d;
    typedef vector<vec2d> vec3d;
    typedef vector<vec3d> vec4d;
    
    int main()
    {
        vec4d v(115, vec3d(4, vec2d(114, vec1d(114))));
    
        for (int i = 0; i < 115; ++i)
        {
            for (int j = 0; j < 4; ++j)
            {
                for (int x = 0; x < 114; ++x)
                {
                    for (int y = 0; y < 114; ++y)
                    {
                        v[i][j][x][y] = 0.0;
                    }
                }
            }
        }
    
        // ...
    }
    

First of all realize how many elements you are storing, which is 115x4x114x114=5 978 160. Each element is a double, which is usually 64 bits (if I remember correctly) so 5 978 160x64=382 602 240 which is 382 megabits. Though this is well within the bounds of modern RAM, do be aware that you are storing quite a lot of data. Next you can use one of three techniques:

Technique 1: Real dynamically allocated multi-dimensional arrays:

This is a tricky one, but basically what you do is you realize that each array is a pointer, your array has 4 dimensions (it is an array of arrays of arrays of arrays of doubles) as such your new array is going to need 4 asterisks! Then you loop through each one useng the new operator to allocate your memory, like so:

double ****array;
//the following loops may be in reverse order, I cannot remember if you do 115-4-114-114 or 114-114-4-115
array=new double***[115];
for (int i=0; i<115; ++i)
{
    array[i]=new double**[4];
    for (int ii=0; ii<4; ++ii)
    {
        array[i][ii]=new double*[114];
        for (int iii=0; iii<114; ++iii)
            array[i][ii][iii]=new double[114];
    }
}

and now you can use array just as if it were as posted above.

Technique 2: Real multi-dimensional vector:

This is a bit less tricky, but do note that > > has a space between the symbols! Basically you make a vector of vectors of vectors of vectors of doubles.

vector<vector<vector<vector<double> > > > array;

Technique 3: Fake multi-dimensional vector + wrapper class:

This is by far my favourite technique, basically we use a simple one dimensional array, then write a class that accesses it as a multidimensional array.

class my_115_4_114_114_DoubleArray
{
    private:
    vector<double> vals;//stores the data
    public:
    double &operator()(int a, int b, int c, int d)//the same as [a][b][c][d]
    {
         //the formula for multidimensional emulation is:
         //d1*x1+d2*x2+...+dn+xn where n is the dimension and d is the size of it and x is the index of it
         return vals[4*114*114*a+114*114*b+114*c+d];//correct me if I am wrong someone!
    }
};

As a bonus, you could write a class that stores n-dimensional arrays of size n, which you could then port to other projects. (I have a working version I could post if you want)

Hope this helps!

Edited 4 Years Ago by Labdabeta: made a few errors

This question has already been answered. Start a new discussion instead.