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 yourstruct Car_list_, treat that as an array, andreallocthat when it's fullstruct Car_ cars_[];flexible-length array in yourstruct 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 acceptstruct Car_list_**rather than juststruct Car_list_*because you'll need to be able to communicate the address change ofstruct Car_list_*to the caller (returning the newstruct Car_list_*is also an option)Adding another layer of indirection and separately
mallocing eachstruct Car*is probably a waste, but you could do that too and add a*to each of the two above choices accordingly.