2

I am trying to allocated a 2D array. I am seeing a lot of people use loops when they allocated(Dynamically allocated 2d array), but I am still unsure if a person always needs to use a loop to allocate a 2d-array in C. Do I need the loop because my code only allocates one column?

int ** allocate(int width, int height){
    int **array = malloc(sizeof(int *) * width);
    array[i] = malloc(sizeof(int) * height);
    return array;

}
Community
  • 1
  • 1
J_Dawg
  • 17
  • 1

3 Answers3

5

No, you don't always need a loop.

int (*array)[M] = malloc( sizeof *array * N ); 

The code above declares array as a pointer to an M-element array of int, then allocates enough space for N instances of that array type, giving us storage for an N by M array of int.

If the size of M is not known at compile time, then array is a variable-length array, which isn't supported in C89 or earlier.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 1
    It is worth to note that such 2D array is to be placed within continuous memory location, which is not the case for the "heap fragmentation" method. – Grzegorz Szpetkowski Jun 08 '16 at 20:15
  • Side note: This will always make square arrays. If you want "jagged" arrays (e.g. the first row as 5 cols, the second row has 3 cols, etc.), you can do this with explicit mallocs on each row – ellman121 Jun 08 '16 at 20:43
1

There are two different common ways to create a 2D array in C. If the inner dimension is fixed (i.e., known at compile time), you can declare it as an array of those fixed-size arrays, and then just allocate one big blob of memory. If you don't, then you have to allocate an array of pointers to rows, then do a loop allocating each row.

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
0

See for instance How do I allocate a 2 D array with contigious memory ? How Do I use it to access rows and columns? Give me an example

If the thing that is to be avoided is the multiple calls to malloc(), then here is an alternative way to allocate a 2D array:

int row=42;
int col=35;
int** array=malloc(row*sizeof(int*));
if(array==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
array[0]=malloc(row*col*sizeof(int));
if(array[0]==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
int i;
for(i=1;i<row;i++){
    array[i]=&array[0][i*col];
}
...
free(array[0]);
free(array);

Values can still be retreived by int val=array[i][j] and set by array[i][j]=42;

Compared to the method that is introduced in your question, the present method ensures that the rows are contiguous in memory. Hence, such array of float or double can easily be used by the LAPACK library as a matrix, of by the FFTW library to compute the 2D Fast Fourier Transform of an image (convolution...). But increasing the size of the array on the fly is much harder.

Notice that the size of the array can be computed by the program at execution time, days after the program is compiled.

This trick can be extended to higher dimensions (3D, 4D,...) but it does not become more beautiful !

Community
  • 1
  • 1
francis
  • 9,525
  • 2
  • 25
  • 41