I have two C structs: _Car_
, which describes a car, and _Car_List_
, which describes a list of cars and contains a dynamic array called cars_
. However, when the condition on reallocating memory for cars_
(to avoid an overflow) is triggered the following code stops working:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
struct _Car_
{
char* name_;
int id_;
};
struct _Car_List_
{
int number_of_cars_;
int max_number_of_cars_;
struct _Car_* cars_[];
};
struct _Car_* createCar(int id, char* name)
{
struct _Car_* car = malloc(sizeof(struct _Car_));
if (car == NULL)
return NULL;
car->name_ = name;
car->id_ = id;
return car;
}
int addCar(struct _Car_List_* car_list, int id, char* name)
{
struct _Car_* car = createCar(id, name);
if (car_list->number_of_cars_ == car_list->max_number_of_cars_)
{
car_list->max_number_of_cars_ = car_list->max_number_of_cars_ + SIZE;
car_list = realloc(car_list, sizeof(struct _Car_List_) + car_list->max_number_of_cars_ * sizeof(struct _Car_*));
if (car_list->cars_ == NULL)
return -1;
}
car_list->cars_[car_list->number_of_cars_] = car;
car_list->number_of_cars_++;
return 0;
}
void printCars(struct _Car_List_* car_list)
{
int i = 0;
struct _Car_* car = car_list->cars_[i];
while (i < car_list->number_of_cars_)
{
printf("- %s [%d]", car->name_, car->id_);
printf("\n");
i++;
car = car_list->cars_[i];
}
}
int main()
{
// Here we initialise our list of cars.
struct _Car_List_* car_list = malloc(sizeof(struct _Car_List_) + SIZE * sizeof(struct _Car_*));
car_list->number_of_cars_ = 0;
car_list->max_number_of_cars_ = SIZE;
printf("Num of cars = %d\n", car_list->number_of_cars_);
addCar(car_list, 1, "A");
printf("Num of cars = %d\n", car_list->number_of_cars_);
addCar(car_list, 2, "B");
printf("Num of cars = %d\n", car_list->number_of_cars_);
addCar(car_list, 3, "C");
printf("Num of cars = %d\n", car_list->number_of_cars_);
addCar(car_list, 4, "D");
printf("Num of cars = %d\n", car_list->number_of_cars_);
printCars(car_list);
return 0;
}
Could you please tell me what I am doing wrong?
You're using reserved names. Don't start a globals and tags with an underscore. And never start anything with _[_A-Z]
.
But most importantly, it's unclear what you want to realloc
.
You basically have two choices:
struct Car_* cars_;
in your struct Car_list_
, treat that as an array, and realloc
that when it's fullstruct Car_ cars_[];
flexible-length array in your struct Car_list_
and realloc the whole thing while accounting for the size needed for the preceding members when the flexible array is full . In this case, your resizing "methods" would need to accept struct Car_list_**
rather than just struct Car_list_*
because you'll need to be able to communicate the address change of struct Car_list_*
to the caller (returning the new struct Car_list_*
is also an option)Adding another layer of indirection and separately malloc
ing each struct Car*
is probably a waste, but you could do that too and add a *
to each of the two above choices accordingly.