I am trying to create an array of arrays but the the number of subarrays is unknown.
-
1Use `malloc` for the array and you can use `realloc` to enlarge it. for ints for example declare as `int **myArrays;` – Paul Ogilvie Dec 22 '20 at 15:39
-
You can generally use `malloc` to create such 'jagged' arrays. But more details and clarity in your question would help to get a specific answer. – Adrian Mole Dec 22 '20 at 15:40
-
Does this answer your question? [How do I declare a 2d array in C++ using new?](https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new) – DevUt Dec 22 '20 at 15:52
-
1Are all the subarrays the same length? If so, the array can be easily defined as a single variable length array, or allocated as a single, dynamically allocated block (using `malloc` or `calloc`) rather than as an array of pointers to the first elements of different length subarrays (which would be 'jagged'). – Ian Abbott Dec 22 '20 at 15:54
-
2@DevUt note that `new` and `delete` are C++ operators, while OP asks about C – Expolarity Dec 22 '20 at 15:57
-
1This question is a bit minimalistic. Which made me tend to answer: "What you do not know, you do not need." – alk Dec 22 '20 at 16:02
5 Answers
Jagged array is array of arrays such that member arrays can be of different sizes, i.e., we can create a 2-D array but with a variable number of columns in each row.
Static Jagged Array:
int kk0[4] = { 1, 2, 3, 4 };
int kk1[2] = { 5, 6 };
int* jagged[2] = { kk0, kk1 };
Dynamic Jagged Array:
int* jagged[2];
jagged[0] = malloc(sizeof(int) * 1);
jagged[1] = malloc(sizeof(int) * 3);
Reference : https://en.wikipedia.org/wiki/Jagged_array

- 2,533
- 2
- 14
- 26
-
Better word: "*[A] jagged array can be accessed like an array of arrays ...*", because it explicitly is **not** an array of arrays, but a ... well ... "jagged" array. – alk Dec 22 '20 at 16:00
-
Good, heard first time **Jagged**, but only problem is sequential access is not possible – IrAM Dec 22 '20 at 16:01
-
1
-
Also "jagged" arrays can be created to use exactly one continuous block of memory. – alk Dec 22 '20 at 16:03
"create an array of arrays but the the number of subarrays is unknown."
If using C99
, or a compiler since then that supports variable length arrays (optional since C11), this would provide a way to do this at run-time. A short example:
#define ARRAY_BASE_SIZE 20 //known at compile time
int main()
{
int numSubArrays = 0;
printf("enter a value for number of sub-arrays:\n");
int count = scanf("%d", &numSubArrays);//not known until run-time
if(count == 1)
{
int array[ARRAY_BASE_SIZE][numSubArrays];
memset(array, 0, sizeof(array));
}
return 0;
}

- 22,849
- 3
- 43
- 87
-
-
@alk - Actually since C99 (which of course is older) , that's why I included the statement _"If using C99, or a compiler since then_ that supports _"_ But thanks . – ryyker Dec 22 '20 at 16:10
-
Ahyes, well, fair enough. Still explicitly mentioning C99 then is either redundant or just half the truth. ;) – alk Dec 22 '20 at 16:12
-
@Alk - I only do that as it is a common way to introduce [VLAs](https://en.wikipedia.org/wiki/Variable-length_array) (look at the Implementation section). But why do you say that it is redundant. Do you not feel it is important to qualify the suggestion by limiting it to only a sub-set of compilers? (I have always provided that disclaimer when mentioning VLA.) – ryyker Dec 22 '20 at 16:14
-
1
-
@Alk - Its been awhile since I've seen you around the C pages. I forgot how much fun you can be. – ryyker Dec 22 '20 at 16:33
-
1Well, I felt as I tent to mostly pick on other peoples postings, I perhaps needed to turn to something completly new, put on the noob cap again, so I decide to dive into understanding and manoeuvering this kind of machines: https://www.mycloud.ch/l/P0084C2443AE29CB8EEC34CBE23C06E54F3551AE464C7677295E9C84C8AB1FB3A .... thousands of pages of new old documentation to read, knobs to to turn, button to switch, ... ;) Today I stumnbled in here more or less by .. well let's say accident. But to be honest it *is* fun being here ... again ;) – alk Dec 22 '20 at 16:54
-
If the number of sub arrays is not known then the array must be expandable when there are more sub arrays than you thought.
int **myArrays; // the array of arrays
int nSubArrays= 0; // its current size
int nUsed= 0; // how many have been used
#define INCREMENT 5 // increment for alocation
myArrays= malloc(sizeof(int *) * INCREMENT);
nSubArrays= INCREMENT;
nUsed= 0;
now fill the array(s):
myArrays[nUsed]= fillSubArray();
nUsed++;
and expand the array when it becomes full:
if (nUsed==nSubArrays) {
int **tmp= realloc(myArrays, sizeof(int *)*(nSubArrays+INCREMENT));
if (!tmp) return 0; // error
myArrays= tmp;
nSubArrays += INCREMENT;

- 25,048
- 4
- 23
- 41
In C it is very common practice to declare a pointer and reference it as an array. In C an array will decay to a pointer when the reference of the array is assigned to the pointer. To reference an array of arrays, it is common to declare a pointer-to-pointer, assign it to the reference of a 2-D array, and later index it like a 2-D array.
The following are all equivalent. argv
is an array of array of char
. Using []
makes your intention of using indexing a pointer as an array clear to other programmers who might be reading your code.
char **argv;
char *argv[];
char argv[][]; (this is wrong)
The size of the array is usually communicated separately. In fact, the parameters of the main
function does just that. When you see
int main(int argc, char *argv[]);
The char *argv[]
is an array of array of characters (aka array of strings) passed from the command line. The argument argc
represents the number of arrays in argv
. To index the first element in the array, use argv[0]
, whose type is will be char*
(aka char[]
).
-
-
This shows how to declare them but not how to allocate. See Paul's comment - you want to include `malloc` or `realloc`. – rutgersmike Dec 22 '20 at 16:30
-
How about this, its just an attempt to give a start point, not the complete answer, but we can build on this.
Also we need to keep track of size
of each subarray to access valid locations, am sure that can be done easily by some kind of book keeping.
#include <stdio.h>
#include <stdlib.h>
#define BASE_SIZE 3
int main()
{
int** dyn_array = NULL;
int countSubArray = 0;
int count = 0;
int size = 0;
dyn_array = malloc(sizeof (int* ) * BASE_SIZE);
if ( dyn_array ) {
printf("enter number of subarrays:");
scanf("%d", &countSubArray);
while( count < countSubArray) {
printf("enter sizeof %d subarray", count+1);
scanf("%d", &size);
if ( dyn_array[count] = malloc(sizeof (int) * size) )
{
printf("Allocated sub array %d at %p\n",count+1, (void*) dyn_array[count]);
}
count++;
}
}
return 0;
}

- 1,720
- 5
- 18