-1

Normally, when I create a dynamic 2D array I will first malloc the row pointers, then loop through rows and malloc each of rows. So, for example:

array = malloc( row_count * sizeof( int* ) );
for( int x = 0; x < row_count; x++ ){
    array[x] = malloc( column_count * sizeof( int ) );
}

Once this is done I can use a syntax like:

data[3][5] = 52;

to set or get the values. The problem with this is that many mallocs are done which is both cpu-intensive and results in many fragments of memory, all of which have to be deallocated individually. The alternative is to allocate the array as a single block of memory. However, if I do this, I can no longer use the [ ][ ] syntax to refer to elements in the array and instead I have to do something like this:

data[ row_index * column_size + column_index ] = 52;

manually calculating the correct offset into the contiguous block. Is there a way to allocate a single block of memory for an array, yet still use the [ ][ ] syntax?

Tyler Durden
  • 11,156
  • 9
  • 64
  • 126
  • There is only one way to allocate a 2D array. And that would indeed only use a single `malloc` call. Anything else is not a 2D array. And of course you have to use the nested index operators (or addition/dereference, but that is exactly the same) for a 2D array. – too honest for this site Jul 13 '17 at 15:55
  • An idea I had a while back is to allocate memory for a single array, then also make an array of pointers pointing to array[0], array[colsize], array[2*colsize], etc. You only use malloc once, but keep some extra pointers around. Not sure if it's actually possible to implement cleanly, or if it's worth the trouble though.EDIT: check the answer to the question above – neoaggelos Jul 13 '17 at 15:56
  • @neoaggelos: That would not be a 2D array. – too honest for this site Jul 13 '17 at 15:58
  • @EugeneSh. That "duplicate" has nothing to do with my question. I am not "converting" anything. – Tyler Durden Jul 13 '17 at 16:04

1 Answers1

5

If variable length array types are available (since C99; made optional in C11, but widely available), you can use something like:

size_t rows, cols;

/* calculate rows and cols based on user input, etc. */

int (*data)[cols] = malloc(sizeof *data * rows);

to allocate contiguous space that can be indexed as a 2d array.

If the number of rows is unknown, but the number of columns is known at compile time, you can use, even without VLAs:

#define COLS  10   /* or some known compile-time value */

size_t rows;

/* calculate rows based on user input, etc. */

int (*data)[COLS] = malloc(sizeof *data * rows);
ad absurdum
  • 19,498
  • 5
  • 37
  • 60