.
You really should NOT do this! (This is take you out behind the woodshed bad code!)
2D-Arrays in C/C++ are a pointer to a block of memory of size rows*columns*sizeof(datatype) bytes. (Possibly with the addition of a little alignment padding.)
The actual [row][column] dimensions exist only statically at compile time. There's nothing there dynamically at runtime!
So, as others have mentioned, you can in fact treat:
int array [ rows ] [ columns ];
As:
int array [ rows * columns ]
Or (well almost, if we exclude alignment padding):
void * array = malloc ( rows * columns * sizeof(int) );
Next: Declaring a variably sized array. Some compilers permit alloca() (cough, GNU). Some don't. Upshot, under g++/Linux, this is permissible:
int main( int argc, char ** argv )
{
UASSERT( argc, >, 2 ); // My own macro...
int rows = atoi( argv[1] );
int columns = atoi( argv[2] );
int data [ rows ] [ columns ]; // Yes, legal!
memset( data, 0, sizeof(data) );
print( data, rows, columns );
manipulate( data, rows, columns );
print( data, rows, columns );
}
Passing the variably-sized data array around is more problematic. You either need to receive it as a void*, or cast away the array'ness ((int*) data) when invoking manipulate()/print().
Generally speaking, you cannot cast to an array type. But you can circumvent that restriction if you play dirty. (Didn't I just say this was take you out behind the woodshed bad code!)
void manipulate( void * theRealData, int theRows, int theColumns )
{
int (* p) [ theRows ] [ theColumns ];
*(void **)&p = theRealData; //Need *&. Issue with casting lvalues.
for ( int r = 0; r < theRows; r ++ )
for ( int c = 0; c < theColumns; c ++ )
(*p) [r] [c] = r*10 + c;
}
void print( void *theRealData, int theRows, int theColumns )
{
int (* p) [ theRows ] [ theColumns ];
*(void **)&p = theRealData; //Need *&. Issue with casting lvalues.
for ( int r = 0; r < theRows; r ++ )
{
for ( int c = 0; c < theColumns; c ++ )
{
cout << (*p) [r] [c] << " ";
}
cout << endl;
}
cout << endl;
}
All that said, I'd use Guge's solution: int data [ theRows * theColumns ] or int * data = new int [ theRows * theColumns ] and a GET macro/function/method. (data[r*theColumns + c])
Ideally all wrapped up in a nice class/struct, to simplify passing it around.
Intelligence is knowing how to make it work.
Wisdom is knowing enough not to do it!