Reputation: 101
Objective
Dynamically create an array of an array of Element strucs (defined below)
typedef struct {
void* data;
} Element;
Question
I know how to malloc an array of Element strucs
Element* arrayOfElements = malloc(4 * sizeof(Element));
But then how do I Malloc an array of the above? (an array of arrayOfElements)
Question 2
Lets say the array of arrayOfElements is called arrayOfArrayStruc how would I proceed to set values inside of it
For Example I want to copy 65 to arrayOfElements[2] which is inside arrayOfArrayStruc1 how would I got about that ?
I know how to do that if I wanted to copy 65 straight to arrayOfElements[2]
arrayOfElements[2].data = malloc( sizeof(int) );
ptr = arrayOfElements[2].data;
*ptr = 65;
but im not sure how to do that if arrayOfElements[2] is inside arrayOfArrayStruc1.
EDIT
To make it more clear my goal i've made a picture
So in green is the structure Element defined by
typedef struct {
void* data;
} Element;
Then in red ( which had 4 green boxes) is an Array of Element structures which I malloc'd using
Element* arrayOfElements = malloc(4 * sizeof(Element));
What im looking to do is store the above ^^ in an array or make an array of pointers (which is the blue box with red boxes in it)
So in the picture "Array Of Element" holds 4 Element Structures, then I want to make an array to store 4 "Array Of Element" (or an array of 4 pointers to point to each "Array of Element")
Upvotes: 0
Views: 625
Reputation: 36082
If you want an array of Element* then you could do something like this where is n
is the number of pointers:
Element** arrayOfStructs = malloc( n* sizeof(Element*) );
So for n = 4; you get an array of 4 pointers:
arrayOfStructs
+---+
| | ->
+---+
| | ->
+---+
| | ->
+---+
| | ->
+---+
Now allocate for each entry in the arrayOfStructs so if m
is the number of Elements:
for (int i = 0; i < n; ++i)
{
arrayOfStructs[i] = malloc(m * sizeof(Element));
}
Since each element has a data pointer, you need to allocate what that points to as well:
for (int i = 0; i < n; ++i)
{
arrayOfStructs[i] = malloc(m * sizeof(Element));
for (int j = 0; j < m; ++j)
{
arrayOfStructs[i][j].data = malloc(sizeof(int));
}
}
After this you will have the following in memory:
Let's say m = 3;
arrayOfStructs
+---+ +---+---+----+
| | -> | | | | array of Elements
+---+ +---+---+----+ +---+---+----+
| | -------------------> | | | |
+---+ +---+---+----+ +---+---+----+
| | -> | | | |
+---+ +---+---+----+ +---+---+----+
| | -------------------> | | | |
+---+ +---+---+----+
each element in "array of Elements" 1..3(or rather 0..2) point to a different "data" (below on array of Elements is turned around 90 degrees so I can more easily draw boxes):
+---+ +---+
| | -> | | integer
+---+ +---+ +---+
| | ---------> | |
+---+ +---+ +---+
| | -------------------> | |
+---+ +---+
Upvotes: 1
Reputation: 141574
arrayOfElements
is the name of a pointer variable. You cannot have an array of names.
You could have an array of pointer variables. You can write the code for that, it is the same as the code for an array of int, but use a pointer type instead of int. Then, you would need to initialize each of those pointer variables in the array the same way as you are doing now.
However, as posted, the question asked for "array of arrays", not "array of pointers". An "array of arrays" is an array where the element type is an array (not a pointer).
Here is a non-dynamically-allocated array: int x[4][5];
. This is an array of 4 elements, with each element being an array of 5 ints.
To dynamically allocate one of these, it is the same code as dynamically allocating any array of 4 elements. We just use int[5]
as the element type, instead of int
or whatever.
The type of the pointer to the first element is: "pointer to int[5]
". In C syntax this is written int (*)[5]
-- not int *[5]
which is an array of pointers.
One way to write the code would be:
int (*px)[5] = malloc(4 * sizeof(int[5]));
hopefully you can see the similarity between this and the malloc
in your question. We just replaced Element
with int[5]
. (So, your job now, is to use Element[5]
instead of int[5]
. Or whatever size instead of 5
).
To avoid repetition (and so avoid the possibility of errors) it's possible to use the common idiom:
int (*px)[5] = malloc(4 * sizeof *px);
which is 4 elements each of the right size for what the pointer is pointing to.
Upvotes: 1