我有两个 C 结构体:
_Car_
,它描述一辆汽车;_Car_List_
,它描述汽车列表并包含一个名为 cars_
的动态数组。但是,当触发为 cars_
重新分配内存(以避免溢出)的条件时,以下代码将停止工作:
#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;
}
你能告诉我我做错了什么吗?
您正在使用保留名称。不要以下划线开头全局变量和标签。永远不要以
_[_A-Z]
开始任何事情。
但最重要的是,不清楚你想要什么
realloc
。
你基本上有两个选择:
struct Car_* cars_;
中有一个 struct Car_list_
,将其视为一个数组,当它已满时realloc
struct Car_ cars_[];
中有一个 struct Car_list_
灵活长度数组,并重新分配整个数组,同时在弹性数组已满时考虑前面成员所需的大小。在这种情况下,您的调整大小“方法”将需要接受 struct Car_list_**
而不仅仅是 struct Car_list_*
添加另一层间接层并分别对每个
malloc
进行 struct Car*
可能是一种浪费,但您也可以这样做,并相应地为上述两个选择添加一个 *
。
您使用了无效的指针
当您在 addCar 中重新分配 car_list 时,您将返回 0 或 -1,而不是新分配的 car_list,因此在 main 中您正在读取旧指针,即垃圾内存,
您应该更改函数addCar以返回新重新分配的car_list,或者向该函数传递一个指向指针的指针