简体   繁体   中英

Creating array of struct inside another struct

I am having trouble in code:

typedef struct{
    int a;
    int b;
} Passenger;

typedef struct{
    int amount;
    Passenger bus_array[amount];
} Bus;

The amount undeclared here.

You have two alternatives, both involves dynamic memory allocation. The big difference is what structure you're allocating dynamically.


The first alternative is using a pointer instead of an array:

typedef struct{
    int amount;
    Passenger *bus_array;
} Bus;

Once you know the value of amount you can allocate memory for bus_array :

Bus my_bus;
bus.amount = get_passenger_amount();
bus.bus_array = malloc(bus.amount * sizeof(Passenger));

The second alternative is using an flexible array member (as I mentioned in a comment):

typedef struct{
    int amount;
    Passenger bus_array[];
} Bus;

Then you need to allocate the Bus structure dynamically:

int amount = get_passenger_amount();

Bus *my_bus = malloc(sizeof(Bus) + amount * sizeof(Passenger));
my_bus->amount = amount;

There are some differences between the two methods that might be worth to note. The most important is that the first method makes two separate and distinct allocations: One for the Bus structure and another for the bus_array . The second method there is only a single combined allocation for all of the Bus structure as well as bus_array .

Here

typedef struct{
  int amount;
  Passenger bus_array[amount];
} Bus;

When compiler see the below statement

Passenger bus_array[amount];

it doesn't know how much memory to allocate for bus_array because amount is unknown for compiler at this stage. Hence it throws the error.

Instead of

Passenger bus_array[amount];

you can use

Passenger *bus_array;

and later on you can allocate memory for bus_array equal to amount bytes when compiler knows what is amount .

Adding to @Achai's correct answer, and because you asked, I would allocate memory for the passengers like this:

typedef struct{
  int amount;
  Passenger *bus_array;
} Bus;

Bus emptyBus = { 0, NULL}; // use this to initialize new buses so that pointer and amount are zero.

void changeAmount(Bus *bus, int amount)
{
  bus->amount = amount;
  free(bus->bus_array); // freeing a null pointer is OK.
  bus->bus_array = malloc(sizeof(Passenger)*amount);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM