Reputation: 25
struct A {
int num,
struct B *data0, *data1 , *data2
};
For the above sample code, the number of "data" might change. Currently, it's 3. Suppose I want to get input from the user and accordingly allocate memory to it. I was thinking of converting it into an array, something like *data[].
But then how to dynamically allocate this array and also access it since each member should be a valid pointer to struct B
Upvotes: 1
Views: 245
Reputation: 44274
For sure you should use an array-like style when the number of "data" members can change.
Flexible array-member as suggested by @O__________ in another answer is good if struct A
is always dynamic allocated and you don't need to change the number of pointers in the array af creation.
If you want struct A
to be a local variable (automatic storage duration) or need to change size after creation, you can do:
struct A
{
int num;
struct B **data;
};
and allocate like:
struct A a;
a.num = getSizeFromUser();
a.data = malloc(a.num * sizeof *a.data);
Now a.data
can be used as an array of struct B
pointers. Example:
struct B b;
a.data[0] = &b; // Point to an object with automatic storage
a.data[1] = malloc(sizeof *a.data[0]); // Point to an object with allocated storage
and then you can for instance do
a.data[1]->SomeDataMemberOfStructB = someValue;
Using realloc
you can even change the number of pointers during program execution, e.g. start with 8 pointers and later increase to 16 pointers.
Upvotes: 0
Reputation: 67546
Before you start dynamically allocate struct members is good to know the C language struct syntax.
struct A
{
size_t num;
struct B data[];
};
struct A *alloc(size_t numdata)
{
struct A *data = malloc(szieof(*data) + numdata * sizeof(data -> data[0]));
if(data) data -> num = numdata;
return data;
}
If you want to store pointers:
struct A
{
size_t num;
struct B *data[];
};
or 2D array:
#define NCOLUMNS 100
struct A
{
size_t num;
struct B data[][NCOLUMNS];
};
or 3D array
#define NCOLUMNS 200
#define NROWS 100
struct A
{
size_t num;
struct B data[][NROWS][NCOLUMNS];
};
etc etc
The alloc function will remain the same (here you can see why using the objects is much better than types in the sizeof
)
Upvotes: 1