tags:

views:

69

answers:

3

Hi, there is a topic about this subject which is working with arrays but I can't make it work with matrices.

(Topic: http://stackoverflow.com/questions/312116/c-array-size-dependent-on-function-parameter-causes-compile-errors)

In summary:

  long rows, columns;
  cin >> rows >> columns;
  char *a = new char [rows];    

compiles great in visual studio, but:

  char **a = new char[rows][columns]; 

or

  char *a[] = new char[rows][columns];

or

  char *a[] = new char[rows][columns]();

or

  char **a = new char[rows][columns]();

don't compile at all.

Any help? Thank you

+4  A: 

The array-new operator only allocates 1-dimensional arrays. There are different solutions, depending on what sort of array structure you want. For dimensions only known at runtime, you can either create an array of arrays:

char **a = new char*[rows];
for (int i = 0; i < rows; ++i) {
    a[i] = new char[columns];
}

or an array of elements with an associated array of pointers to the first element of each row (requiring just two hits to the memory allocator):

char *a = new char[rows*columns];
char **a = new char*[rows];
for (int i = 0; i < rows; ++i) {
    a[i] = a + i*columns;
}

Either one will let you access matrix elements via a[row][column].

An alternate solution is to just use the one-dimensional array and generate indexes by hand:

char *a = new char[rows*columns];
...
a[columns*row + column]

This is probably faster than the double-indirection required in the first two solutions.

You could of course wrap this in a class to preserve a semblance of 2D indexing syntax:

class MatrixWrapper {
    ...
    char& operator()(int row, int column) { return a_[columns*row + column]; }
    ...
};
...
a(row, column)
Marcelo Cantos
Marcelo works great. Too many years without using C/C++ and I didn't remember anything. Thanks
Do note that there is a performance implication of using char** over char* for a 2d-array. (Not just the extra pointer lookup... I'd wager it'll be mostly due to cache misses and the likes..)
Marcus Lindblom
+1  A: 

A n-dimensional array can not be directly allocated as you are trying to. Here is a way to do it.

int main(){
    unsigned int **p;
    unsigned int rows = 10;
    unsigned int cols = 20;

    p = new unsigned int* [rows];

    for(size_t row = 0; row < rows; row++){
        p[row] = new unsigned int [cols];
    }

    for(size_t row = 0; row < rows; row++){
        delete [] p[row];
    }

    delete [] p;
}
Chubsdad
A: 

If you're going to use c-arrays in c++ (instead of std::vector), you're stuck doing something like this:

long rows    = 0;
long columns = 0;
cin >> rows >> columns;

// declaration
long** a = new long* [rows];
for(long i = 0; i < rows; ++i)
{
    a[i] = new long[cols];
}

// initialization
for(long j = 0; j < rows; ++j)
{
    for(long i = 0; i < rows; i++)
    {
        a[i][j] = 0;
    }
}

// delete sub-arrays
for(long i = 0; i < rows; ++i)
{
    delete[] a[i];
}

// delete array
delete[] a;
luke
I don't think the OP was insisting on anything. Plus, vector doesn't do 2D, and you really shouldn't recommend anyone to use valarray (see [here](http://stackoverflow.com/questions/1602451/c-valarray-vs-vector)).
Marcelo Cantos
Language changed, valarray reference removed.
luke