Связанные списки, Назначение массива символов [C] - PullRequest
2 голосов
/ 21 октября 2010

У меня есть задача составить программу проката автомобилей, которая использует связанные списки для контроля того, какие автомобили можно арендовать, арендовать или ремонтировать.«Автомобиль» - это структура, а также арендованный список, доступный список и список ремонта.

Вот моя текущая проблема.Если пользователь хочет сделать новый автомобиль доступным, мы должны добавить его в наш список всех возможных автомобилей, и мы должны добавить его в список доступных автомобилей.

У меня нет проблем с добавлением его в списокавтомобилей, но когда мне нужно добавить его в список доступных автомобилей, я получаю ошибку сегментации.

Я сейчас предоставлю код:

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

}car;

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

Список всех автомобилей:

car * carHead, * carCur;

Список всех доступных автомобилей:

carList * availHead, * availCur;

Оба инициализируются как NULL.

Затем я создаю новый автомобиль и вставляю данные, которые пользователь дал мне (пробег и идентификационный номер)

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;

Это прекрасно работает.Я вызываю функцию, которая фактически добавляет его в список, все хорошо.

Затем я создаю новую структуру 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;

После некоторого тестированияиспользуя операторы printf (которые для краткости не включены здесь), я обнаружил, что в этом выражении возникает ошибка сегмента.

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

Я надеюсь, что кто-то может сказать мне, почему это назначение приводит к ошибке сегмента.Я проверил idNum, предоставленный пользователем, хорошо, и он работает для добавления в список всех автомобилей, поэтому я не уверен, что не так.

Я ценю помощь!

Ответы [ 5 ]

3 голосов
/ 21 октября 2010

Вы правы относительно точки сбоя сегмента.
Вы правильно распределяете память

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

на данный момент availCur->aCar является висящим указателем. Далее вы разыменовываете этот указатель здесь

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

и это приводит к сбою.

Чтобы исправить это, вам нужно выделить память для автомобильного объекта и заставить availCur->aCar указать на него, прежде чем начинать его заполнять.

2 голосов
/ 21 октября 2010

Вы не выделили никакой памяти для aCar, который является указателем на car. Когда вы пытаетесь сослаться на поле внутри aCar, вы пытаетесь получить доступ к памяти, которой просто не существует, отсюда ошибка сегментации.

В зависимости от того, что вы хотите, чтобы список доступных автомобилей содержал, есть ряд возможных мер. Предположим, что вы хотите, чтобы каждая запись в списке доступных автомобилей соответствовала записи в списке всех автомобилей, вы можете просто указать точку поля aCar для существующего автомобиля в списке автомобилей. С другой стороны, если вы хотите, чтобы в списке доступных автомобилей содержался собственный набор автомобилей, вам необходимо сначала выделить память для автомобиля, затем назначить его для aCar и заполнить его поля.

1 голос
/ 21 октября 2010

Этот код:

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

страшен и, скорее всего, сломан.Если пользователь не вызывает со строкой, содержащей не менее 20 допустимых символов, существует высокий риск сбоя.Вы хотите:

strcpy(carCur->idNum, idNum);
1 голос
/ 21 октября 2010

Несколько вещей:

  1. Почему у вас есть связанный список автомобилей и связанный список связанных автомобилей (car и carList)?
  2. fprintf(stderr, "...") лучше для отладки, потому что сообщения не будут задерживаться;printf("...") может быть буферизовано, что может привести к тому, что вы не получите самый последний вывод в случае сбоя программы.
  3. Вы не присвоили availCar->aCar перед разыменованием.Вам нужно availCar->aCar = (car *)malloc(sizeof(car)), прежде чем вы сможете использовать availCar->aCar->....
0 голосов
/ 21 октября 2010

Лучше всего было бы создать класс list и поместить конструктор, который выделит память для члена aCar и деструктор, чтобы освободить эту память (конечно, для этого нужно перейти на C ++).

...