1

I have a question about a code snippet provided by following post: https://stackoverflow.com/a/3912959/3668527

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

Now, I figured out a few days ago that *array[rows] would mean an array of pointers which each points to a one-dimensional array allocated with malloc. These arrays are scattered everywhere in the memory.

It would be the same as if I did the following, except that for the former I don't need to free() the pointer array while for the following, I have to free everything.

int **array = (int **)malloc(sizeof *array * rows);

(I included the cast of the malloc, because the compiler helped me understand this by directing me what type the variable is. Otherwise it would have been more difficult to understand this.)

But the code snippet at the top is completely different. Could someone tell me how the top code snippet is exactly called, so that I can do some reading on it? When I search for dynamically allocated VLAs, I can only find information about array[rows][cols]. I cannot find this pointer in ( and ) brackets which can allocate a block of memory just like array[rows][cols], but don't need rows and cols to be known at compile time.

Edit: My question is a duplicate of pointer to array type, c

mkdrive2
  • 268
  • 1
  • 14
  • In C you don't need to cast your `malloc()` call. – tadman Jan 04 '23 at 16:36
  • Do you want a 2D array, an array of pointers to other arrays, or a 1D array? – tadman Jan 04 '23 at 16:37
  • This is confusing because it's mixing two techniques: it's a dynamically allocated array of VLA's. At the outer level we have a `malloc` call that allocates `rows` number of somethings. And the somethings are (one-dimensional) VLA's of `int`, specifically `cols` number of them. – Steve Summit Jan 04 '23 at 16:37
  • @tadman The code snippet is for a 2D array block which is dynamically allocated at runtime. But like I said, the size of the block is not needed at compile time. – mkdrive2 Jan 04 '23 at 16:38
  • 1
    The 100% VLA solution would be `int array[cols][rows];`. The posted solution might be more clear (would be more idiomatic) if expressed as `int (*array)[cols] = malloc(rows * sizeof(array[0]));`. – Steve Summit Jan 04 '23 at 16:40
  • But in any case, what you have here is a true two-dimensional array (that is, an array of arrays); you do *not* have a "simulated two-dimensional array", or a bunch of pointers to pointers, `int **`. – Steve Summit Jan 04 '23 at 16:42
  • Dynamically allocating two-dimensional arrays has always been tricky in C: You either need to use the "simulated" (aka "ragged") pointer-to-pointer technique, or the inner dimension (`cols`) needs to be known at compile time, or you need to use VLA's. – Steve Summit Jan 04 '23 at 16:43
  • 1
    @user3121023 Thanks, this is exactly what I wanted! I think what complicated things was that `cols` was a variable, and I did not understand it because of that. – mkdrive2 Jan 04 '23 at 17:08
  • I think my question is a duplicate and can be closed. – mkdrive2 Jan 04 '23 at 17:12

1 Answers1

1
  1. Better
int (*array)[cols] = malloc(rows * sizeof(*array));

int (*array)[cols] declares a pointer to array of cols integers.

This way you allocate continuous memory for the whole array and assign it to the pointer to the array.

  1. int **array = malloc(rows * sizeof(*array); allocates memory for rows number of pointers. Then you must to allocate memory for the integers you want to store. You have two levels of indirection (code will be slower), complicated allocation and deallocation.
0___________
  • 60,014
  • 4
  • 34
  • 74
  • They mean that `array` is a pointer to (one or more) arrays of `cols` integers. – Steve Summit Jan 04 '23 at 16:51
  • 2
    @mkdrive2: `int *array[cols]` means "an array with `cols` elements of type pointer to `int`", whereas `int (*array)[cols]` means "a single pointer to an array with `cols` elements of type `int`". – Jonathan Leffler Jan 04 '23 at 17:41