2010-10-21 9 views
2

J'ai pour tâche de créer un programme de location de voitures, qui utilise des listes chaînées pour contrôler quelles voitures sont disponibles à la location, louées ou en réparation. La «voiture» est une structure, tout comme la liste louée, la liste disponible et la liste de réparation.Listes liées, assignation de tableau de caractères [C]

Voici mon numéro actuel. Si l'utilisateur veut faire une nouvelle voiture disponible, nous devons l'ajouter à notre liste de toutes les voitures possibles, et nous devons l'ajouter à la liste des voitures disponibles.

Je n'ai aucun problème à l'ajouter à la liste des voitures, mais quand j'ai besoin de l'ajouter à la liste des voitures disponibles, je reçois un défaut de segmentation.

Je vais maintenant fournir le code:

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

}car; 

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

La liste de toutes les voitures est:

car * carHead, * carCur; 

La liste de toutes les voitures disponibles est:

carList * availHead, * availCur; 

Les deux sont initialisés à NULL.

Je crée alors une nouvelle voiture, et mis dans les données que l'utilisateur m'a donné (nombre de kilométrage et 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; 

Cela fonctionne parfaitement bien. J'appelle la fonction qui l'ajoute réellement à la liste, tout va bien.

Ensuite, je crée une nouvelle structure carList à ajouter à la liste des voitures disponibles.

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; 

Après quelques essais en utilisant printf, (qui werent tout compris ici par souci de concision), je trouve la faute de seg se produit dans cette déclaration. J'espère que quelqu'un peut me dire pourquoi cette affectation entraîne une erreur de segmentation. J'ai vérifié le idNum fourni par l'utilisateur est bon, et cela fonctionne pour ajouter à la liste de toutes les voitures, donc je ne suis pas sûr de ce qui ne va pas.

J'apprécie l'aide!

Répondre

3

Vous avez raison sur le point de seg faute.
Vous allouez la mémoire correctement

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

à ce point availCur->aCar est un pointeur ballants. Ensuite, vous déréférencer ce pointeur ici

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

et cela provoque le blocage.

Pour résoudre ce problème, vous devez allouer de la mémoire à un objet de voiture et lui indiquer availCur->aCar avant de commencer à le bourrer.

+0

Merci, j'ai choisi votre réponse, car elle est la plus concise, et répond très directement à la question. – Blackbinary

2

Vous n'avez alloué aucune mémoire pour aCar, qui est un pointeur vers un car. Lorsque vous essayez de référencer un champ à l'intérieur de aCar, vous essayez d'accéder à la mémoire qui n'existe tout simplement pas, d'où l'erreur de segmentation.

En fonction de ce que vous voulez que la liste des voitures disponibles soit disponible, il existe un certain nombre de solutions possibles. Supposons que vous voulez que chaque entrée de la liste des voitures disponibles corresponde à une entrée dans la liste de toutes les voitures, vous pouvez simplement avoir votre point de terrain aCar sur une voiture existante dans la liste des voitures. D'un autre côté, si vous souhaitez que la liste de voitures disponible contienne son propre ensemble de voitures, vous devez d'abord allouer de la mémoire pour une voiture, puis l'affecter à aCar et remplir ses champs.

+0

merci pour l'aide, et l'explication de mes options. Je fais le dernier, car c'était la façon dont j'ai été dirigé dans la tâche. – Blackbinary

1

Quelques choses:

  1. Pourquoi avez-vous une liste chaînée de voitures, et une liste chaînée des listes chaînées de voitures (car et carList)? Est mieux pour le débogage car les messages ne seront pas retardés;
  2. printf("...") peut être mis en mémoire tampon, ce qui vous empêche de générer la sortie la plus récente lorsque le programme se bloque. Vous n'avez pas affecté availCar->aCar avant de le déréférencer. Vous avez besoin d'un availCar->aCar = (car *)malloc(sizeof(car)) avant de pouvoir utiliser availCar->aCar->....
+0

merci, je ne savais pas cette différence. J'utiliserai fprintf maintenant :) – Blackbinary

1

Ce code:

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

est effrayant et très probablement cassé. Si l'utilisateur n'appelle pas avec une chaîne contenant au moins 20 caractères valides, il risque de s'écraser. Vous voulez:

strcpy(carCur->idNum, idNum); 
+0

merci, ça fait un moment pour moi, j'ai oublié strcpy. – Blackbinary

-1

Le mieux serait de créer une classe list et de mettre un constructeur qui allouer de la mémoire pour aCar membre et un destructor pour libérer cette mémoire (bien sûr, vous devez passer à C++ pour le faire) .

+0

Je ne suis pas sûr que ce soit une bonne suggestion. Vous dites essentiellement "passer à OOP". ce qui n'aide pas avec la question. – Blackbinary