Harsh Agarwal
Harsh Agarwal

Reputation: 25

Dynamically allocate a member of a structure which is also a structure

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

Answers (2)

4386427
4386427

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

0___________
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

Related Questions