简体   繁体   English

链表,分配char数组[C]

[英]Linked Lists, Assigning char array [C]

I've got the task of making a car rental program, which uses linked lists to control what cars are available for rent, are rented, or are in repair. 我的任务是制定汽车租赁程序,该程序使用链接列表来控制哪些汽车可供出租,已出租或正在维修。 The 'car' is a structure, and so is the rented list, available list, and repair list. “汽车”是一种结构,租赁列表,可用列表和维修列表也是如此。

Heres my current issue. 这是我当前的问题。 If the user wants to make a new car available, we must add it to our list of all possible cars, and we must add it to the list of available cars. 如果用户希望提供新车,我们必须将其添加到所有可能的车列表中,并且必须将其添加到可用车列表中。

I have no problem adding it to the list of cars, but when i need to add it to the list of available cars, i get a segmentation fault. 我将它添加到汽车列表中没有问题,但是当我需要将其添加到可用汽车列表中时,出现了细分错误。

I will now provide the code: 我现在将提供代码:

typedef struct vehicles
{
    char idNum[20];
    int miles;
    int rDate;
    struct vehicles *nextCar;

}car;

typedef struct list
{
    car * aCar;
    struct list *nextCar;
} carList;

The list of all cars is: 所有汽车的清单是:

car * carHead, * carCur;

The list of all available cars is: 所有可用汽车的列表是:

carList * availHead, * availCur;

Both are initialized to NULL. 两者都初始化为NULL。

I then create a new car, and put in the data the user has given me (mileage and ID number) 然后,我创建一辆新车,并输入用户给我的数据(里程数和ID号)

carCur = (car *)malloc(sizeof(car));
//set ID, Mileage
for(k=0;k<=19;k++)
{
     carCur->idNum[k] = idNum[k];
}
carCur->miles = miles;
carCur->nextCar = NULL;

This works perfectly fine. 这工作得很好。 I call the function which actually adds it to the list, all is well. 我调用了实际上将其添加到列表中的函数,一切都很好。

Then i create a new carList structure to be added to the available cars list. 然后,我创建一个新的carList结构,将其添加到可用的汽车列表中。

availCur = (carList *)malloc(sizeof(carList));
//set ID, Mileage
for(k=0;k<=19;k++)
{
    availCur->aCar->idNum[k] = idNum[k];
    printf("assigned\n");
}
availCur->aCar->miles = miles;
availCur->nextCar = NULL;

After some testing using printf statements,(which werent all included here for brevity), i found the seg fault occurs in this statement. 经过一些使用printf语句的测试(为简洁起见,此处未全部包括在内),我发现此语句中出现了段错误。

    availCur->aCar->idNum[k] = idNum[k];

I'm hoping someone can tell me why this assignment results in a segfault. 我希望有人能告诉我为什么此作业会导致段错误。 I've checked the idNum provided by the user is good, and it works for adding to the all-cars list, so I'm not sure what is wrong. 我检查了idNum提供的idNum很好,并且可以将其添加到所有汽车列表中,因此我不确定这是什么错误。

I appreciate the help! 感谢您的帮助!

You are right about the point of seg fault. 您对段错误的观点是正确的。
You are allocating memory correctly 您正在正确分配内存

availCur = (carList *)malloc(sizeof(carList));

at this point availCur->aCar is a dangling pointer. 此时availCur->aCar是一个悬空指针。 Next you are dereferencing that pointer here 接下来,您在这里取消引用该指针

availCur->aCar->idNum[k]
              ^^

and this causes the crash. 这会导致崩溃。

To fix this you need to allocate memory for a car object and make availCur->aCar point to it before you start stuffing it. 要解决此问题,您需要先为汽车对象分配内存,然后在开始填充它之前使availCur->aCar指向该对象。

You haven't allocated any memory for aCar , which is a pointer to a car . 您尚未为aCar分配任何内存, aCarcar的指针。 When you try and reference a field inside aCar you're trying to access memory that simply doesn't exist, hence the segmentation fault. 当您尝试引用aCar一个字段时,您试图访问的是根本不存在的内存,因此出现了分段错误。

Depending on what you want the available car list to hold there's a number of possible remedies. 根据您希望可用的汽车清单所包含的内容,有许多可能的补救措施。 Suppose you want each entry in the available car list to correspond to an entry in the list of all cars, you can simply have your aCar field point at an existing car in the car list. 假设您希望可用汽车列表中的每个条目都与所有汽车列表中的条目相对应,则只需将aCar字段指向汽车列表中的现有汽车即可。 On the other hand, if you want the available car list to hold its own set of cars, you need to first allocate memory for a car, then assign it to aCar and populate its fields. 另一方面,如果希望可用的汽车列表包含自己的汽车组,则需要首先为汽车分配内存,然后将其分配给aCar并填充其字段。

A few things: 一些东西:

  1. Why do you have a linked list of cars, and a linked list of linked lists of cars ( car and carList )? 为什么会有汽车的链表和汽车的链表( carcarList )的carList
  2. fprintf(stderr, "...") is better for debugging because the messages will not be delayed; fprintf(stderr, "...")更适合调试,因为消息不会延迟; printf("...") may be buffered, causing you to not have the most recent output when the program crashes. printf("...")可能会被缓冲,导致程序崩溃时您没有最新的输出。
  3. You did not assign availCar->aCar before dereferencing it. 在取消引用之前,您没有分配availCar->aCar You need a availCar->aCar = (car *)malloc(sizeof(car)) before you can use availCar->aCar->... . 您需要先使用availCar->aCar = (car *)malloc(sizeof(car))才能使用availCar->aCar->...

This code: 这段代码:

for(k=0;k<=19;k++)
{
     carCur->idNum[k] = idNum[k];
}

is scary and very likely broken. 很恐怖,很可能坏了。 If the user doesn't call with a string containing at least 20 valid characters, it runs a high risk of crashing. 如果用户不使用包含至少20个有效字符的字符串进行调用,则很有可能发生崩溃。 You want: 你要:

strcpy(carCur->idNum, idNum);

最好的办法是创建一个list类,然后放置一个构造函数,该构造函数将为aCar成员分配内存,并释放一个析构函数以释放该内存(当然,您需要移动到C ++来做到这一点)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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