multidimensional array

I've got this code under main:
1
2
3
4
cout << "n= ";
    cin >> n;
	bool m[n][n]; //expected constant expression *-*- cannot allocate array of constant size 0 *-*- missing subscript *-*- unknown size
    input_m( m, n ); // cannot convert parameter 1 from 'bool[][1]' to 'bool**' 

and this other one under
input_m( m, n );
1
2
3
4
5
6
7
8
9
10
11
12
13
void input_m( bool** m, int n ){
    for( int i=0; i<n; i++ ){
        for( int j=i; j<n; j++ ){
            cout << "matrix[" << i << "][" << j << "] = ";
            while(!( cin >> m[i][j] )){
                cin.clear();
                cin.ignore( 1000, '\n' );
                cout << "matrix[" << i << "][" << j << "] = ";
            }
        }
    }
    return;
}


what's wrong with it ?
it gives several errors marked as comments
is there even a difference between 'bool[][1]' and 'bool**' ?
thanks
When declaring an array, whether it is multidimensional or not, the size must be constant. If you want the user to determine the size, you can use dynamic allocation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//const example
const int n(10);
bool input_m[n][n];

//Dynamic allocation
int n(0);
cin >> n;
bool** m = new bool[n];
for(int I=0; I<n; ++I)
   m[I] = new bool[n];
//bool* m = new bool[n*n]; //Alternative
//...
//Don't forget to deallocate the memory
for(int I=0; I<n; ++I)
   delete[] m[I];
delete[] m;
//delete[] m; //For the alternate version 
from the looks of it, bool [x][y] and bool ** are NOT at all the same.

(correct me if im wrong)

if you have bool [x] [y] , x and y are both stored in the memory while the program is running.
so when you compile the computer finds somewhere to put x and y when your run the executable.

so bool ** is the supposed memory location for a hypothetical 2-dimensional bool array.
so it doesnt understand it when you make a parameter 'm', because m is the name of the array!
( bool [m] [1] )

i think it should be bool
[z] [1]; or
bool [n] [1];

also change

but if you dont change :

bool m [n] [n]
--

, make

bool [any character] [n];

hope this helps!!!
if i declare it normally all under main it works:
1
2
cin >> n;
bool m[n][n];

it only gives an error when i try to pass the dynamic bidimensional array to a function
void input_m( bool** m, int n );
the above will give an error.
void input_m( bool m[5][5], int n );
the above will work without any error.
so my new question is:
how do i pass a dynamic array to a function ?
is there a way to pass the memory location of the two pointers and then treat them later as indexes ?
how do i get the address of m[0][0] ?
or is there a way to declare globally under main ?
Last edited on
is there even a difference between 'bool[][1]' and 'bool**' [parameters]

?

Yes

A bool[][1] parameter accepts (the address of the first element of) an N by 1 array, where N is a positive integer, e.g.

1
2
3
4
bool arr1[][1] = {true};
bool arr2[][1] = {true, false};
bool arr5[][1] = {true, true, false, true, false};
// etc 


As the parameter is an array, the function (or rather, the compiler) assumes that the elements are laid out contiguously in memory, as they are for arrays of all sizes, 2D and otherwise.

The compiler also know that that all the elements are in the same size, so when you give it the row and column, it can work out where an element is in memory with respect to the start address: row x <row length + col. (This need to know the row length -- or nuber of columns -- is why you can it the second size in e.g. arr[][3].)

A bool** parameter accepts any double pointer to bool -- pointers to pointers of single bools and bool* arrays, but not 2D bool arrays.

Here, ppfoo is a bool**

1
2
3
bool foo = true;
bool* pfoo = &foo;
bool** ppfoo = &pfoo;


And so is pbar in this snippet

1
2
3
4
5
6
7
bool a_bool = true;
bool another_bool = false;
bool bool_array = {true, false, true};

bool* bar[] = {&a_bool, &another_bool, bool_array};

bool** pbar = bar;


Now, if you create a bool* array which contains bool arrays of the same size, then the bool** array can pretend to be an array. But (a) the memory layout is not contiguous, and (b) not all the involved array elements are the same size. So it is not actually an array.

(The char** array contains bool* pointers which will typically be a 32 or 64 bit values, compared with the 8 bits generally used to store bool values. So moving from row to row requires the compiler to move a pointer by 32 or 64 bits, where it's only 8 bits from column to column (or element to element, on the same row.)

The conclusion?

Given the issues to do with memory layout, you can hopefully see why the C++ compiler does not allow you to cast from array address to a pointer to pointer. So that makes (real) 2D arrays awkward to use with functions (but not impossible, if you use templates).

But is doesn't stop you from char** pretend arrays, These pretend arrays are particularly popular with people who haven't yet seen the light and realised how evil they really are! After all, they can even be allocated dynamically on the heap.

(I do note here, for those who know the C++ standard library, that using a std::vector of std::vectors isn't quite as evil, but it's not the best solution, either.)

For further information, see these cplusplus.com articles:

Multidimentional arrays are evil
http://www.cplusplus.com/articles/G8hv0pDG/
- for why you shouldn't use multi-dimensional arrays outside of a programming exercise.

Multi-Dimensional Arrays
http://www.cplusplus.com/articles/NAUq5Di1/
- for examples of how to use "evil" multi-dimensional arrays

The difference between pointers and arrays
http://www.cplusplus.com/articles/NUCRko23/
- and
Array is not pointer
http://www.cplusplus.com/articles/2TA0RXSz/
- for more about the differences between pointers and arrays

So, given that multi-dimensional arrays are evil, what should you use instead? As the "evil" article mentioned above says, you should use a 1D array and handle the translation from 2D to 1D indexing youself (rather than letting the compiler do it for you.) Of course, as you're a C++ programmer (I hope!) you'd abstract this translation mechanism nicely away inside a class. As does the sample that ends the article.

Andy
Last edited on
@frescofrs

Regarding...

it only gives an error when i try to pass the dynamic bidimensional array to a function
void input_m( bool** m, int n );
the above will give an error.
void input_m( bool m[5][5], int n );
the above will work without any error.
so my new question is:
how do i pass a dynamic array to a function ?
is there a way to pass the memory location of the two pointers and then treat them later as indexes ?
how do i get the address of m[0][0] ?
or is there a way to declare globally under main ?

please see above material, including the links, before asking additional questions.

Andy

PS Note that this code snippet

1
2
cin >> n;
bool m[n][n]; 


relies on C99 varable sized arrays, which some compilers (well, notably VC++) do not support. Arrays must be declared with constant sizes, or allocated on the heap with new.
Last edited on
Topic archived. No new replies allowed.