3-dimensional dynamically allocated array

I am trying to make a 3-dimensional array dynamically but I got errors.
This is my code.

1
2
3
4
5
6
7
void CTest::Start(int NumOfTester, int NumOfParts, int ColData)
{
    double Test[][][];

    Test = new double[NumOfTester][NumOfParts][ColData];

}


This is my error
Serious error: C2950E: Illegal in lvalue: function or array 'Test'

I know from the start that the above code was wrong.

I also tried editing this code for 2-dimensional array but I still got errors.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//from professional C++ 2005 e-book
char** allocateCharacterBoard(int xDimension, int yDimension)
{
    char** myArray = new char*[xDimension]; // Allocate first dimension
    
    for (int i = 0; i < xDimension; i++) {
        myArray[i] = new char[yDimension]; // Allocate ith subarray
    }
    return myArray;
}

void releaseCharacterBoard(char** myArray, int xDimension)
{
    for (int i = 0; i < xDimension; i++) {
        delete[] myArray[i]; // Delete ith subarray
    }
    delete[] myArray; // Delete first dimension
}


Can anyone modify this code? or ...
Thanks a lot.
double Test[][][];

Try double*** Test = new double[NumOfTester][NumOfParts][ColData](0);
Which will create a dynamic 3D array with contents initialized to zero.

The issue here is that if NumOfTester is 100, NumOfParts is 50 and ColData is 25... you'll store 100*50*25*8 (assuming x86 architecture) bytes of memory. Thats 1 MiB...
Last edited on
closed account (z05DSL3A)
chrisname wrote:
Thats 1 MiB
Not quite 1 MiB, you are 48576 bytes shy. ;0)
Last edited on
Is this legal c++? I get errors when i try to initialize a 3D array like that!

What you could do is:
1
2
3
4
5
6
7
8
9
10
double*** t = reinterpret_cast<double***>(new double[1*2*3]); // BEWARE reinterpret cast is evil!

//the more common approach is
  double*** t = new double**[1];
  for(int i = 0 ; i < 1; ++i){
    t[i] = new double*[2];
    for(int j = 0; j < 2; ++j){
      t[i][j] = new double[3];
    }
  }
closed account (z05DSL3A)
olredixsis,

If you want code like your professional C++ 2005 e-book, it would be along the lines of:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
double*** Allocate_3D_Double_Array(int x, int y, int z)
{
    double*** the_array = new double**[x];
    for(int i(0); i < x; ++i)
    {
        the_array[i] = new double*[y];

        for(int j(0); j < y; ++j)
        {
            the_array[i][j] = new double[z];

            for(int k(0); k < z; ++k)
            {
                the_array[i][j][k]= 0.;
            }
        }
    }
    return the_array;
}

void release_3D_Double_Array(double*** the_array, int x, int y, int z)
{
    for (int i = 0; i < x; ++i) 
    {
        for (int j = 0; j < y; ++j)
        {
            delete [] the_array[i][j];
        }
        delete [] the_array[i];
    }
    delete [] the_array;
}

int main()
{
    double*** ptr = Allocate_3D_Double_Array(3, 3, 3);

    //....

    release_3D_Double_Array(ptr, 3, 3, 3);

    return 0;
}


But it may be better to use vectors for your 'array' e.g. vector< vector< vector< double> > > a_3D_Array;

@Grey Wolf,
My mistake. It's 1 MB.
closed account (z05DSL3A)
:0)
It is a MB in 'decimal' SI units but not the 'binary' SI units. You would be better off saying 0.95 MiB to avoid confusion. It was better back in the day when computer people knew if you said kB* you meant 210 and not 103.

*Yes it is a lowercase K.
The way I've learnt it is that one MegaByte is 1000 kiloBytes; which is 1000 bytes. One MebiByte is 1024 kibiBytes which is 1024 Bytes. 1000 * 1000 (1 MB) is equal to 1,000,000 and so is 100 * 50 * 25 * 8. 1024 * 1024 is equal to 1048576, as you pointed out.

*Yes it is a lowercase K.
I know.
@chrisname
double*** Test = new double[NumOfTester][NumOfParts][ColData](0);


I got errors when I compiled the above code.
The errors were:
line 420: Error: C2501E: 'new' <array> initialiser ignored
line 420: Error: C3028E: <initialisation>: implicit cast of pointer to non-equal pointer

here is my code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void CMyAppSetupMenu::StartMeasurement()
{
	int i,j,k;
	const int NumOfTester = 3, NumOfParts = 10, ColData = 5;//sample value only.. for initialization

	double*** Test = new double[NumOfTester][NumOfParts][ColData](0);
	
//	NumOfAppraiser = GetMSAInfo().AppraiserInfo();
//	NumOfParts = GetMSAInfo().Parts();

//	CMyApp_Ctrl* MyApp;

//	DefineNominalWeight();

	for(i = 0; i < NumOfTester; i++)
	{	
		for(j = 0; j < 3; j++)
		{
			for(k = 0; k < NumOfParts; k++)
			{
				Test[i][j][k] = ObtainedWeight(); //store data... 
			}//end for
		}//end for
	}//end for

}//end StartMeasurement 


@Grey Wolf
The code you posted works. I am still confused with vectors. Would you mind posting a 3-dimensional vectors? Thanks

@all
Hmm.. how can I declare a 3-dimensional stack-based array with a non constant index? thanks.

Last edited on
closed account (z05DSL3A)
olredixsis wrote:
I am still confused with vectors. Would you mind posting a 3-dimensional vectors?

it would be along the lines of:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <vector>
using std::vector;

int main() 
{
    const int HEIGHT(3);
    const int WIDTH(3);
    const int DEPTH(3);

    vector< vector< vector< double > > > a_3D_Array;

    a_3D_Array.resize(HEIGHT);
    for (int i = 0; i < HEIGHT; ++i) 
    {
        a_3D_Array[i].resize(WIDTH);

        for (int j = 0; j < WIDTH; ++j)
        {
            a_3D_Array[i][j].resize(DEPTH);
        }
    }

    a_3D_Array[0][0][0] = 1.0;

    return 0;
}
closed account (z05DSL3A)
chrisname,

The way I've learnt it is that one MegaByte is 1000 kiloBytes; which is 1000 bytes...

Context is all important here, for example; if you go to a computer manufacturer, the spec for a PC may have 4GB of Ram and a 500GB HDD. Now the GB for the RAM is going to be 230 but the GB for the HDD is likely to be 109 and the OS may well report the drive size in terms of 230.

Somewhere around the year 2000, the IEC introduced the *bi prefix to try to work around this duality in the SI system (technically I don't think the binary version was ever official SI, more de facto) but I don't think it has taken yet, I hardly ever see the *bi prefix used.

The only reason I bought it up is because I believe it is important to know

             SI                 |       IEC
Name (symbol)  Std SI   Binary  | Name (symbol)  Value
------------------------------------------------------
kilobyte  (kB)	10^3	2^10	| kibibyte (KiB) 2^10
megabyte  (MB)	10^6	2^20	| mebibyte (MiB) 2^20
gigabyte  (GB)	10^9	2^30	| gibibyte (GiB) 2^30
terabyte  (TB)	10^12	2^40	| tebibyte (TiB) 2^40
petabyte  (PB)	10^15	2^50	| pebibyte (PiB) 2^50
exabyte   (EB)	10^18	2^60	| exbibyte (EiB) 2^60
zettabyte (ZB)	10^21	2^70	| zebibyte (ZiB) 2^70
yottabyte (YB)	10^24	2^80	| yobibyte (YiB) 2^80



Do you know about Boost::Multi_array (http://www.boost.org/doc/libs/1_43_0/libs/multi_array/doc/index.html)?
It´s very easy, safe and performatic way to work with 3D arrays.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <boost/multi_array.hpp>

using namespace std;
using namespace boost;

typedef multi_array<double, 3> Array3D;

int main(int argc, char *argv[])
{
    const int nX = 100;
    const int nY = 250;
    const int nZ = 75;

    Array3D myArray(extents[nX][nY][nZ]);
    myArray[23][12][66] = 7.7;
    cout << myArray[23][12][66] << endl;

    return EXIT_SUCCESS;
}


You don't need to worry with deallocation and other little details of manual dinamic memory allocations.
@GreyWolf
Do I need to deallocate the code you posted using vector? or is it a stack-based vector? since there were no "new" keyword. thanks.

@augustorighetto
Thanks for the reply.
Hmm.. the problem is.. I don't want to use other libraries just standard libraries only.
Correct me if I'm wrong, if you included boost or other libraries except for the "default" libraries others should include also that libraries in order to execute the program am I right? thanks.
Topic archived. No new replies allowed.