I am mainly interested in the viability of shrinking such an array.
I\'m working on a project where I have used single malloc() calls to each create individ
Using multidimensional arrays, this can be done with or without pointers to variable length arrays. Since you probably don't want to allocate any additional memory, this will be done in place.
First allocate a 20 by 10 array:
int ( *array )[10] = malloc( sizeof(int ) * 20 * 10 );
for( size_t i = 0 ; i < 20 ; i++ )
for( size_t j = 0 ; j < 10 ; j++ )
array[i][j] = i * 100 + j;
If you want to change the number of rows, no elements have to be moved, only a realloc is needed. Changing the row count to 15 is trivial:
array = realloc( array , sizeof( int ) * 15 * 10 );
If you want to change the column count, then the elements will have to be moved. Since we don't need to copy the first column, the copying starts at the second one. Function memmove is used to avoid memory overlap, which cannot happen in this case, but it could if the new column count were larger. Also it avoids aliasing problems. Note that this code is defined only because we are using allocated memory. Let's change the column count to 3:
int (*newarray)[3] = ( int(*)[3] )array;
for( size_t j = 1 ; j < 15 ; j++ )
memmove( newarray[j] , array[j] , sizeof( int ) * 3 );
newarray = realloc( array , sizeof( int ) * 15 * 3 );
Working example: https://ideone.com/JMdJO0
If the new column count happens to be larger than the old one, then the memory will have to be reallocated first (to simply get more space), and then the column copying will take place, instead starting at the last column.