views:

229

answers:

6

hey,

i want to allocate a matrix.

is this the only option:

int** mat = (int**)malloc(rows * sizeof(int*))

for (int index=0;index<row;++index)
{
    mat[index] = (int*)malloc(col * sizeof(int));
}

thanks

+2  A: 

How about just:

int* mat = malloc(rows * columns * sizeof(int));
Paul Betts
+4  A: 

Well, you didn't give us a complete implementation. I assume that you meant.

int **mat = (int **)malloc(rows * sizeof(int*));
for(int i = 0; i < rows; i++) mat[i] = (int *)malloc(cols * sizeof(int));

Here's another option:

int *mat = (int *)malloc(rows * cols * sizeof(int));

Then, you simulate the matrix using

int offset = i * cols + j;
// now mat[offset] corresponds to m(i, j)

for row-major ordering and

int offset = i + rows * j;
// not mat[offset] corresponds to m(i, j)

for column-major ordering.

One of these two options is actually the preferred way of handling a matrix in C. This is because now the matrix will be stored contiguously in memory and you benefit from locality of reference. Basically, the CPU cache will a lot happier with you.

Jason
if your compiler supports variable-length arrays or if `cols` is a compile-time constant, you don't even need to compute the offsets yourself; if you use `int (*mat)[cols] = malloc(rows * sizeof *mat)`, you can access the elements via `mat[i][j]` and still use a contiguous block of memory
Christoph
Even ignoring performance, a single allocation is also preferable because it's simpler. There are fewer things to deallocate later, and there's no need to deal with partial allocation failures.
jamesdlin
A: 

You may also use calloc, which will additionally zero initialize the matrix for you. The signature is slightly different:

int *mat = (int *)calloc(rows * cols, sizeof(int));
Shtééf
A: 

You can collapse it to one call to malloc, but if you want to use a 2d array style, you still need the for loop.

int** matrix = (int*)malloc(rows * cols * sizeof(int) + rows * sizeof(int*));

for (int i = 0; i < rows; i++) {
    matrix[i] = matrix + rows * sizeof(int*) + rows * cols * sizeof(int) * i;
}

Untested, but you get the idea. Otherwise, I'd stick with what Jason suggests.

Matthew Scharley
this only works if `sizeof (int) == sizeof (int *)` - otherwise, the offset will be wrong; it actually might be wrong even if this is the case
Christoph
@Christoph: Good point, and that's easy to work around too, but like I noted in my answer, this is untested. Fixed this now.
Matthew Scharley
A: 

For a N-Dimensional array you can do this:

int *matrix = malloc(D1 * D2 * .. * Dn * sizeof(int)); // Di = Size of dimension i

To access a array cell with the typical way you can do this:

int index = 0;
int curmul = 1;
int i;
int indexes = {I1, I2, ..., In}; // Ii = Index in dimension i

for(i = N-1; i >= 0; i--) {
    index = index + indexes(i) * curmul;
    curmul = curmul * Di;
}

(Note: didnt test now but should work. Translated from my Matlab code, but in Matlab index starts from 1, so i MAY made a mistake (but i dont think so))

Have fun!

George B.
+2  A: 

The other answers already covered these, but for completeness, the comp.lang.c FAQ has a relevant entry:

How can I dynamically allocate a multidimensional array?

jamesdlin