I can't seem to start a new topic here, but I do seem to be able to reply. So I'll post here...
An Easy Way To Solve Problem Of Dynamic Multi-Dimensional Arrays In C++
To solve a problem one must first identify the problem. Here is the problem - MultiDim1.cpp....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
// cl MultiDim01.cpp /O1 /Os /MT
// g++ MultiDim01.cpp -oMultiDim01.exe -mconsole -m64 -Os -s
// 16,384 bytes x64 GCC (TDM GCC 4.8 Series)
#include <cstdio>
int main()
{
int iDim_1,iDim_2,iDim_3,iDim_4;
iDim_1=3, iDim_2=4, iDim_3=5, iDim_4=6; // 3 Rows, 4 Cols, 5 Deep, 6 ??? (don't know what to call 4th Dim!)
int iArray[iD1][iD2][iD3][iD4]; // Create Array
iArray[2][3][4][5]=123456789; // Set some random element
printf("iArray[2][3][4][5] = %d\n",iArray[2][3][4][5]); // Output Value
getchar();
return 0;
}
#if 0
MultiDim01.cpp
MultiDim01.cpp(12) : error C2057: expected constant expression
#endif
| |
The above code tries to create a four dimensional int array with 3 rows, 4 columns, 5 deep (high), and 6 as the 4th dimension - however one wants to visualize or name it. It attempts to be dynamic, i.e., variables rather than constants are used for the four dimensions. This comports with many coding situations where the array sizes needed are only known at run time. This program won't build with any version of Microsoft's compiler tool chain with which I'm familiar. If one attempts to simplify it by using just one simple dimension....
1 2 3 4 5 6 7 8 9 10 11
|
// cl BadArray.cpp
#include <cstdio>
int main()
{
int iNumber=5;
int iArray[iNumber];
return 0;
}
// BadArray.cpp(7) : error C2057: expected constant expression
| |
...the result is the same as seen by the compiler's error message. Interestingly, both these programs build without any problems with GCC's build system, at least with the somewhat dated TDM GCC 4.8 series on this old laptop I'm using. Not only that, MultiDim01.cpp runs correctly. Ignoring Microsoft's compiler (we don't have much choice), lets try to make some progress with this program, and see if we can pass our four dimensional dynamic int array iArray() to a function with GCC's C++ compiler - g++.exe.....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
// g++ MultiDim01A.cpp -oMultiDim01A.exe -mconsole -m64 -Os -s
#include <cstdio>
void Test(int Ar[][][][])
{
printf("Ar[2][3][4][5] = %d\n",Ar[2][3][4][5]);
}
int main()
{
int iDim_1,iDim_2,iDim_3,iDim_4;
iDim_1=3, iDim_2=4, iDim_3=5, iDim_4=6; // 3 Rows, 4 Cols, 5 Deep, 6 ??? (don't know what to call 4th Dim!)
int iArray[iD1][iD2][iD3][iD4]; // Create Array
iArray[2][3][4][5]=123456789; // Set some random element
printf("iArray[2][3][4][5] = %d\n",iArray[2][3][4][5]); // Output Value
Test(iArray[][][][]);
getchar();
return 0;
}
| |
MultiDim01A.cpp:4:24: error: declaration of 'Ar' as multidimensional array must have bounds for all dimensions except the first
So lets try that....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
// g++ MultiDim01A.cpp -oMultiDim01A.exe -mconsole -m64 -Os -s
#include <cstdio>
void Test(int Ar[][4][5][6])
{
printf("Ar[2][3][4][5] = %d\n",Ar[2][3][4][5]);
}
int main()
{
int iDim_1,iDim_2,iDim_3,iDim_4;
iDim_1=3, iDim_2=4, iDim_3=5, iDim_4=6; // 3 Rows, 4 Cols, 5 Deep, 6 ??? (don't know what to call 4th Dim!)
int iArray[iDim_1][iDim_2][iDim_3][iDim_4]; // Create Array
iArray[2][3][4][5]=123456789; // Set some random element
printf("iArray[2][3][4][5] = %d\n",iArray[2][3][4][5]);
Test(iArray[][4][5][6]);
getchar();
return 0;
}
// MultiDim01A.cpp:17:14: error: expected primary-expression before ']' token Test(iArray[][4][5][6]);
| |
I've tried a lot more convolutions of this in my attempts to get a C++ function to accept and understand a multi-dimensional dynamic array, but to save space, my reader's time, and a lot of hide and torn hair I'll refrain from posting any more attempts. Note however, that I'm aware of the C/C++ language technique of considering multi-dimensional arrays as arrays of arrays of a smaller dimension. Clearly though, there's not only a syntax problem here. There's a real problem here for the C/C++ coder.
It's a little hard to understand this, especially considering the fact that C and C++ have always been considered some of the most versatile and powerful programming languages. These are the languages professionals use, and they are used to build operating systems. Basic family languages, on the other hand, are largely viewed poorly by C/C++ practitioners, but in the specific case of PowerBASIC - a Windows programming language with which I'm most familiar, there are no problems whatsoever in dealing elegantly with dynamic multi-dimensional arrays. In the PowerBASIC code below I attempt to utilize an int (Long using PowerBASIC variable naming conventions) dynamic array named iArray() of four dimensions with the array sizing subscripts being 100 for 1st dimension, 100 for 2nd dimension, 100 for 3rd dimension, and 100 for 4th dimension. A C or C++ coder might be inclined to believe this will create a 100 x 100 x 100 x 100 = 100,000,000 element array, but in PowerBASIC the array creating subscript represents the upper bound of the array - not the number of elements of that specific dimension of the array - and like in C or C++ the lower bound is zero. So the array below actually has 101 x 101 x 101 x 101 = 104,060,401 elements, and since each element is four bytes, the dynamic memory allocation from the heap will be 416,241,604 bytes.
Let's take a brief look at the code. Like in MultiDim01A.cpp above, I have a function ArrayOutput(...) with an array parameter specified like so....
ByRef iAr() As Long
The ByRef keyword is optional. By default, PowerBASIC pushes the address of a variable on the stack at the point of a function call, whereas C/C++ family languages push the value at that address on the stack. While passing an array as a function parameter the language does not require any information be provided on the number of dimensions of the array. I believe the language allows up to 8 dimensions. As seen above, the array symbol simply requires an empty set of parentheses after the symbol, i.e.,...
iAr() As Long
I'll have more to say about the significance of this in a bit. Anyway, here is the full code, followed by the compiler output, and then the output from the running program....
continued....