Bonjour, je travaille sur un projet concernant la gestion d'aéroport depuis un bon bout de temps . Afin de pouvoir ajouter un avion dans la liste contennant les avions en attente de décollage, je dois saisir le nom de la compagnie et le reste des informations est saisi automatiquement par les fonctions. Mais il se trouve que lorsque j'ajoute un nouvel avion dans ma liste, j'ai cette erreur : make: *** [makefile:13: EXECUTION] Segmentation fault (core dumped). Et je ne peux pas rajouter un autre avion.
Je pense que l'erreur vient de ma fonction add_plandplane() mais j'ai tenté différente méthode pour la contrer mais sans succès.
Voici mon code et merci à ceux qui apporteront leur soutient.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include "avion.h"
int main()
{
srand(time(NULL));
char ligne[50] ={0}, temp[50] = {0}, *NOM, *ACRONYME; //tableau tampon ligne
int choix, choix2, i, aleatoire, oui, BON;
int ok;
int *identifiant = malloc(3 * sizeof(int));
char NOM_COMP[14][50] = {0};
choix = choix2 = i = 0; aleatoire = CARBURANT(14);
company *companies=NULL, *comp_temp=NULL;
airplane *airplanes = NULL, *avion_temp = NULL;
landing *landplanes = NULL, *offplanes = NULL, *blcompany = NULL, *land_temp = NULL;
//Création des companies, des avions associés et des listes d'avions en atterrissage et décollage
companies = init_company(companies);
airplanes = init_plane(airplanes, companies);
//Listes d'avions en attente de décollage et d'atterrissage
offplanes = init_landplane(offplanes, airplanes, 0, aleatoire, 0, 1);
avion_temp=airplanes; while(i != aleatoire){ avion_temp = avion_temp->suivant; i++; }
landplanes = init_landplane(landplanes, avion_temp, aleatoire, 14, 0, 2);
//Mis à jour du nombre d'avions des compagnies
companies = NOMBRE_AVIONS(companies, offplanes, landplanes);
//affichage_company(companies);
comp_temp = companies;
for (int i = 0; i < 14; i++)
{
strcpy(NOM_COMP[i], comp_temp->nom);
comp_temp = comp_temp->suivant;
}
debut :
system("clear && cat menu_principal.txt");
//METEO();
while(choix<1 || choix>11 || BON != 1)
{
printf("\033[%d;%dH", 11, 14);
BON = scanf("%d", &choix);
int c;
while ((c=getchar()) != '\n' && c != EOF) {
system("clear");
system("cat menu_principal.txt");
printf("\033[%d;%dH", 11, 14);
}
while(choix<1 && choix>11) {
printf("\033[%d;%dH", 11, 14);
BON = scanf("%d", &choix);
}
}
switch(choix)
{
case 1:
c1 :
system("clear && cat add_airplanes.txt");
affichage_landing(offplanes);
printf("\033[%d;%dH", 45, 118);
scanf("%[^\n]%*c", temp);
NOM = (char*)malloc(strlen(temp) * sizeof(char));
NOM = temp;
for(int i = 0; i < 14; i++)
if(strcmp(NOM, NOM_COMP[i]) == 0) ok = 1;
if (ok==1)
{
offplanes = add_landplane(offplanes, NULL, NOM, 1);
//Mis à jour du nombre d'avions des compagnies
comp_temp = companies;
while(comp_temp!=NULL)
{
if (strcmp(NOM, comp_temp->nom)==0)
{
comp_temp->nombre_avions++;
}
comp_temp= comp_temp->suivant;
}
choix = ok = choix2 = 0;
while(choix2<1 || choix2>2 || BON != 1)
{
printf("\033[%d;%dH", 45, 49);
BON = scanf("%d", &choix2);
int c;
while ((c=getchar()) != '\n' && c != EOF) {
system("clear && cat add_airplanes.txt");
printf("\033[%d;%dH", 45, 49);
}
while(choix<1 && choix>2) {
printf("\033[%d;%dH", 45, 49);
BON = scanf("%d", &choix2);
}
if (choix2 == 1) goto debut;
else goto c1;
}
}
else
{
printf("\033[%d;%dH", 47, 97);
printf("Compagnie non présente dans l'aéroport. Entrez un nouveau nom.\n");
sleep(3);
goto c1;
}
break;
case 2:
c2 :
system("clear && cat add_airplanes.txt");
affichage_landing(landplanes);
printf("\033[%d;%dH", 45, 118);
scanf("%[^\n]%*c", temp);
NOM = (char*)malloc(strlen(temp) * sizeof(char));
NOM = temp;
for(int i = 0; i < 14; i++)
if(strcmp(NOM, NOM_COMP[i]) == 0) ok = 1;
if (ok==1)
{
landplanes = add_landplane(landplanes, NULL, NOM, 2);
//Mis à jour du nombre d'avions des compagnies
comp_temp = companies;
while(comp_temp!=NULL)
{
if (strcmp(NOM, comp_temp->nom)==0)
{
comp_temp->nombre_avions++;
}
comp_temp= comp_temp->suivant;
}
choix = ok = choix2 = 0;
while(choix2<1 || choix2>2 || BON != 1)
{
printf("\033[%d;%dH", 45, 49);
BON = scanf("%d", &choix2);
int c;
while ((c=getchar()) != '\n' && c != EOF) {
system("clear && cat add_airplanes.txt");
printf("\033[%d;%dH", 45, 49);
}
while(choix<1 && choix>2) {
printf("\033[%d;%dH", 45, 49);
BON = scanf("%d", &choix2);
}
if (choix2 == 1) goto debut;
else goto c2;
}
}
else
{
printf("\033[%d;%dH", 47, 97);
printf("Compagnie non présente dans l'aéroport. Entrez un nouveau nom.\n");
sleep(3);
goto c2;
}
break;
case 3:
system("clear");
system("cat delete_airplanes.txt");
break;
case 4:
system("clear");
system("cat delete_airplanes.txt");
break;
case 5:
system("clear");
system("cat priority.txt");
break;
case 6:
system("clear");
system("cat blacklist.txt");
break;
case 7:
s :
system("clear");
system("cat display_company.txt");
affichage_company(companies);
printf("\033[%d;%dH", 45, 83);
if(scanf("%d", &oui) != 1)
{
printf("\033[%d;%dH", 47, 53);
printf("Erreur. Sortie du logiciel.\n\n");
}
else if (oui == 1) goto debut;
break;
case 8:
system("clear");
system("cat display_airplane.txt");
affichage_landing(offplanes);
printf("\033[%d;%dH", 45, 49);
if(scanf("%d", &oui) != 1)
{
printf("\033[%d;%dH", 47, 53);
printf("Erreur. Sortie du logiciel.\n\n");
}
else if (oui == 1) goto debut;
break;
case 9:
system("clear");
system("cat display_airplane.txt");
affichage_landing(landplanes);
printf("\033[%d;%dH", 45, 49);
if(scanf("%d", &oui) != 1)
{
printf("\033[%d;%dH", 47, 53);
printf("Erreur. Sortie du logiciel.\n\n");
}
else if (oui == 1) goto debut;
break;
case 10:
system("clear");
system("cat log.txt");
break;
case 11:
system("clear");
//system("cat notice.txt");
break;
}
return 0;
}
avion.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include "avion.h"
//Nombre d'avions présent dans la compagnie
company *NOMBRE_AVIONS(company *ma_compagnie, landing *mon_avion1, landing *mon_avion2)
{
int i = 0;
if (mon_avion1 == NULL && mon_avion2 == NULL) return 0;
else
{
company *comp_temp = ma_compagnie;
landing *avion_temp1, *avion_temp2;
while(comp_temp != NULL)
{
i = 0; avion_temp1 = mon_avion1; avion_temp2 = mon_avion2;
while(avion_temp1 != NULL)
{
if (strcmp(comp_temp->nom, avion_temp1->avion->nom) == 0) i++;
avion_temp1 = avion_temp1->suivant;
}
while(avion_temp2 != NULL)
{
if (strcmp(comp_temp->nom, avion_temp2->avion->nom) == 0) i++;
avion_temp2 = avion_temp2->suivant;
}
comp_temp->nombre_avions += i;
comp_temp = comp_temp->suivant;
}
}
return ma_compagnie;
}
//Génération aléatoire du carburant
int CARBURANT(int i)
{
int kerozen = rand()%i;
return kerozen;
}
int *airplan_id(int *identifiant)
{
identifiant[0] = 'A' + rand()%26;
identifiant[1] = 'A' + rand()%26;
identifiant[2] = ' ';
identifiant[3] = CARBURANT(999999999)+1; // Utilisation de carburant() pour générer une suite de nombre
return identifiant;
}
//Météo
int METEO()
{
int alea, time, meteo = 0;
while(1)
{
alea = rand() % 5;
if(alea == 0) meteo = 1;
else meteo = 0;
if(meteo == 0)
{
printf("\033[%d;%dH", 4, 170);
printf("La météo est bonne\n");
printf("\033[%d;%dH", 5, 170);
printf("SHIOO\n");
printf("\033[%d;%dH", 6, 170);
printf(",zopozzpoe\n");
}
else printf("la météo est mauvaise\n");
time = rand() % 5+3;
sleep(time);
}
}
//Ajout de compagnie
company *add_company(company *ma_compagnie, char *NOM, char *ACRONYME)
{
company *NewCompany = malloc(sizeof(*NewCompany));
NewCompany->suivant = NULL;
// Allocation mémoire pour les noms de compagnies et acronymes
NewCompany->nom = malloc(strlen(NOM) * sizeof(char));
NewCompany->acronyme = malloc(strlen(ACRONYME) * sizeof(char));
company *comp_temp = ma_compagnie;
/* Contrôle si la liste contient au moins un élément. Si ce
* n'est pas le cas on ne fait qu'affecter le nouvel élément.
*/
if (ma_compagnie == NULL) ma_compagnie = NewCompany;
else
{
// Recherche du dernier élément de la liste actuelle
while (comp_temp->suivant != NULL) comp_temp = comp_temp->suivant;
// Affectation de la nouvelle compagnie à la liste de compagnies
comp_temp->suivant = NewCompany;
}
// Affectation des valeurs à nom et acronyme.
memcpy(NewCompany->nom, NOM, sizeof(char)*strlen(NOM));
memcpy(NewCompany->acronyme, ACRONYME, sizeof(char)*strlen(ACRONYME));
return ma_compagnie;
}
//Ajout d'avions
airplane *add_airplane(airplane *mon_avion, company *ma_compagnie, char *NOM, int mode)
{
airplane *NewPlane = malloc(sizeof(*NewPlane));
NewPlane->suivant = NULL;
//Tampon contenant l'identifiant
int *identifiant = malloc(3 * sizeof(int));
identifiant = airplan_id(identifiant);
// Affectation des valeurs à id, carburant et nom en fontion de l'utilisation.
if (mode == 0 || mode == 1 || mode == 2)
{
NewPlane->id = identifiant;
if(mode == 0 || mode == 2) NewPlane->carburant = CARBURANT(100)+1;
else if(mode == 1) NewPlane->carburant = 100;
if (mode == 0)
{
NewPlane->nom = malloc(strlen(ma_compagnie->nom) * sizeof(char));
memcpy(NewPlane->nom, ma_compagnie->nom, strlen(ma_compagnie->nom) * sizeof(char));
}
else if(mode == 1 || mode == 2)
{
NewPlane->nom = malloc(strlen(NOM) * sizeof(char));
memcpy(NewPlane->nom, NOM, strlen(NOM) * sizeof(char));
}
}
airplane *avion_temp = mon_avion;
/* Contrôle si la liste contient au moins un avion. Si ce
* n'est pas le cas on ne fait qu'affecter le nouvel avion.
*/
if (mon_avion == NULL) mon_avion = NewPlane;
else
{
// Recherche du dernier élément de la liste actuelle
while (avion_temp->suivant != NULL) avion_temp = avion_temp->suivant;
// Affectation du nouvel avion à la liste
avion_temp->suivant = NewPlane;
}
return mon_avion;
}
//Création de la liste des avions
airplane *init_plane(airplane *mon_avion, company *ma_compagnie)
{
char *NOM;
if (ma_compagnie == NULL) return 0;
else
mon_avion = add_airplane(mon_avion, ma_compagnie, NOM, 0);
init_plane(mon_avion, ma_compagnie->suivant);
return mon_avion;
}
//Création de la liste des compagnies
company *init_company(company *ma_compagnie)
{
char ligne[50], *NOM, *ACRONYME; //tableau tampon ligne
FILE * fichier = fopen("companies.txt","r"); //ouverture du fichier en lecture avec la fonction fopen()
if (fichier == NULL) //on teste si le fichier existe
{
printf("Ouverture du fichier impossible\n"); //affiche «ouverture ok» si l’ouverture s’est bien passée
exit(1); //on force la sortie de la boucle
}
// Extraction des données du fichier texte et insertion dans la liste chaînée.
while (fgets(ligne,50,fichier) != NULL)
{
NOM = strtok(ligne,"_");
ACRONYME = strtok(NULL,"_");
ma_compagnie = add_company(ma_compagnie, NOM, ACRONYME);
}
return ma_compagnie;
}
//Affichage des compagnies et de leurs caractéristiques
int affichage_company(company *ma_compagnie)
{
int x=13, y = 68;
if (ma_compagnie == NULL) return 0;
else
{
company *comp_temp = ma_compagnie;
while(comp_temp != NULL)
{
printf("\033[%d;%dH", x, y);
printf("%s", comp_temp->nom);
printf("\033[%d;%dH", x, y+42);
printf("%s", comp_temp->acronyme);
printf("\033[%d;%dH", x, y+72);
printf("%d", comp_temp->nombre_avions);
x = x+2;
comp_temp = comp_temp->suivant;
}
}
}
//Affichage des avions et de leurs caractéristiques
int affichage_avion(airplane *mon_avion)
{
if (mon_avion == NULL) return 0;
else
{
printf("NOM = %s\t", mon_avion->nom);
printf("identifiant = %c%c%c%d\t", mon_avion->id[0], mon_avion->id[1], mon_avion->id[2], mon_avion->id[3]);
printf("Carburant = %d\n", mon_avion->carburant);
affichage_avion(mon_avion->suivant);
}
}
//Ajout d'avions en attente d'atterrissage ou de décollage
landing *add_landplane(landing *land, airplane *mon_avion, char *NOM, int mode)
{
//Allocation mémoire pour l'avion et son mode (atterrissage ou décollage)
landing *NewPlane = malloc(sizeof(*NewPlane));
NewPlane->suivant = NULL;
if (mode == 0 || mode == 1 || mode == 2)
{
//Utilisation de carburant() pour générer les horaires
NewPlane->HORAIRE.H = CARBURANT(24);
NewPlane->HORAIRE.M = CARBURANT(60);
if (mode == 1 || mode == 2)
{
//Création d'un avion
airplane *plane = malloc(sizeof(airplane));
plane = add_airplane(plane, NULL, NOM, mode);
NewPlane->avion = plane;
if (mode == 1)
{
NewPlane->MODE = malloc(strlen("TAKEOFF") * sizeof(char));
memcpy(NewPlane->MODE, "TAKEOFF", strlen("TAKEOFF") * sizeof(char));
}
else if (mode == 2)
{
NewPlane->MODE = malloc(strlen("LANDING") * sizeof(char));
memcpy(NewPlane->MODE, "LANDING", strlen("LANDING") * sizeof(char));
}
}
else if (mode == 0) NewPlane->avion = mon_avion;
}
if (land == NULL) return NewPlane;
else
{
landing *land_temp = land;
// Recherche du dernier élément de la liste actuelle
while (land_temp->suivant != NULL) land_temp = land_temp->suivant;
// Affectation du nouvel avion à la liste
land_temp->suivant = NewPlane;
}
return land;
}
//Initialisation des avions en attente de décollage et d'atterrissage
landing *init_landplane(landing *land, airplane *mon_avion, int debut, int fin, int mode, int Amode)
{
if (mon_avion == NULL) return 0;
else
{
airplane *avion_temp = mon_avion;
for (int i = debut; i != fin; i++)
{
land = add_landplane(land, avion_temp, NULL, 0);
avion_temp = avion_temp->suivant;
}
}
//Mode de L'avion
landing *land_temp = land;
while(land_temp != NULL)
{
if (Amode == 1)
{
land_temp->MODE = malloc(strlen("TAKEOFF") * sizeof(char));
memcpy(land_temp->MODE, "TAKEOFF", strlen("TAKEOFF") * sizeof(char));
land_temp->avion->carburant = 100;
}
else if (Amode == 2)
{
land_temp->MODE = malloc(strlen("LANDING") * sizeof(char));
memcpy(land_temp->MODE, "LANDING", strlen("LANDING") * sizeof(char));
}
land_temp = land_temp->suivant;
}
return land;
}
//Affichage des avions et de leurs caractéristiques
int affichage_landing(landing *mon_avion)
{
int x=7, y = 34;
if (mon_avion == NULL) return 0;
else
{
landing *land_temp = mon_avion;
while(land_temp != NULL)
{
printf("\033[%d;%dH", x, y);
printf("%s", land_temp->avion->nom);
printf("\033[%d;%dH", x, y+39);
printf("%c%c%c%d", land_temp->avion->id[0], land_temp->avion->id[1], land_temp->avion->id[2], land_temp->avion->id[3]);
printf("\033[%d;%dH", x, y+75);
printf("%d", land_temp->avion->carburant);
printf("\033[%d;%dH", x, y+105);
printf("%d:%d", land_temp->HORAIRE.H, land_temp->HORAIRE.M);
printf("\033[%d;%dH", x, y+130);
printf("%s\n", land_temp->MODE);
x=x+2;
land_temp = land_temp->suivant;
}
}
}
avion.h
//Définition des structures et listes chaînées nécessaires au bon fonctionnement de l'aéroport
//liste des avions de la compagnie
typedef struct avion airplane;
struct avion{
int *id;
int carburant;
char *nom;
airplane * suivant;
};
//compagnies de l'aéroport
typedef struct compagnie_aerienne company;
struct compagnie_aerienne{
char *nom;
char *acronyme; //acronyme de royal air maroc = RAM
int nombre_avions; // nombres d'avion de la compagnie
company * suivant;
};
// structure contenant le temps
typedef struct temps tim;
struct temps{
int H;
int M;
};
// avions en attente d'atterissage
typedef struct avion_en_atterrissage landing;
struct avion_en_atterrissage{
airplane *avion;
tim HORAIRE;
char *MODE;
landing * suivant;
};
// compagnies black listés
typedef struct black_list BL;
struct black_list{
company ma_compagnie;
BL * suivant;
};
//Gestion de l'aéroport
int CARBURANT(int i);
int *airplan_id(int *identifiant);
int METEO();
company *add_company(company *ma_compagnie, char *NOM, char *ACRONYME);
airplane *add_airplane(airplane *mon_avion, company *ma_compagnie, char *NOM, int mode);
int affichage_company(company *ma_compagnie);
int affichage_avion(airplane *mon_avion);
airplane *init_plane(airplane *mon_avion, company *ma_compagnie);
company *init_company(company *ma_compagnie);
landing * add_landplane(landing *land, airplane *mon_avion, char *NOM, int mode);
company *NOMBRE_AVIONS(company *ma_compagnie, landing *mon_avion1, landing *mon_avion2);
landing *init_landplane(landing *land, airplane *mon_avion, int debut, int fin, int mode, int Amode);
int affichage_landing(landing *mon_avion);
utilises un memory profiler (comme valgrind) après avoir compilé ton projet en mode debug (option -g avec clang/gcc) … tu sauras tout de suite où tu as des accès mémoire fautifs avec la pile d'appel et tout …
Ensuite on y a va au debuger si l'erreur n'est pas évidente.
Si tu as toujours des soucis tu essayes de reproduire l'erreur en faisant un tout petit programme de test et si ça ne va toujours pas alors tu nous montre ce petit programme pour qu'on t'indique ton erreur …
Tu utilises quel compilateur ? Avec GCC il y a une option de compilation pour utiliser gdb.
Si tu n'as pas le temps d'apprendre à utiliser un débogueur, tu peux mettres des 'printf' partout. C'est ce que je fais. Pour corriger une erreur de segmentation, il faut d'abord trouver l'instruction précise qui la déclenche. Pour ça, on met des affichages partout (avec des numéros de ligne). Le plantage s'est produit entre le dernier 'printf' qui s'est affiché et le suivant. Par dichotomie on finit rapidement par trouver cette instruction.
C'est long ? Moins que regarder en vain son listing...
En survolant ton code, à quoi sert le mallloc() pour NAME ligne 81 du main() ? Tu écrases l'adresse donnée par mallloc() à la ligne 82. Le free(NAME) (que tu ne fais pas) plantera. Idem lignes 138 et 139.
Dans le case 2 ligne 130, tu oublies d'initialiser ok à zéro.
Et je suis quasiment certain qu'en allant plus profond, on va trouver d'autres erreurs dans ce genre. Moi j'arrête, trop de code à lire.
- Edité par edgarjacobs 30 décembre 2021 à 23:55:57
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le malloc, c'était un test que je faisais, je l'ai retiré du code.
DU coup, j'ai fait la première étape avec valgrind et j'obtient ça. Que dois-je faire ensuite ?
==5939== Memcheck, a memory error detector
==5939== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5939== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==5939== Command: ./PROJET
==5939==
==5939== Invalid write of size 4
==5939== at 0x10A107: airplan_id (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A383: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5217c is 0 bytes after a block of size 12 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A373: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483EF54: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A3F0: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5135a is 0 bytes after a block of size 10 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A27C: add_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A5B8: init_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109538: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483EF54: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A412: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5135a is 0 bytes after a block of size 10 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A27C: add_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A5B8: init_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109538: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid write of size 4
==5939== at 0x10A107: airplan_id (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A383: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5227c is 0 bytes after a block of size 12 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A373: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483EF54: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A3F0: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a51462 is 0 bytes after a block of size 18 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A27C: add_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A5B8: init_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109538: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483EF54: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A412: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a51462 is 0 bytes after a block of size 18 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A27C: add_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A5B8: init_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109538: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483FEE8: strcmp (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x109FD0: NOMBRE_AVIONS (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109620: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5135a is 0 bytes after a block of size 10 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A27C: add_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A5B8: init_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109538: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483FEF0: strcmp (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x109FD0: NOMBRE_AVIONS (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109620: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a521ca is 0 bytes after a block of size 10 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A3F8: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483FEE8: strcmp (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A00A: NOMBRE_AVIONS (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109620: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5196f is 0 bytes after a block of size 15 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A27C: add_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A5B8: init_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109538: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483FEF0: strcmp (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A00A: NOMBRE_AVIONS (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109620: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a527df is 0 bytes after a block of size 15 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A3F8: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A51C: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
==5939== Invalid read of size 1
==5939== at 0x483F0B2: strcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x109681: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5135a is 0 bytes after a block of size 10 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A27C: add_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A5B8: init_company (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109538: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
DU coup, j'ai fait la première étape avec valgrind et j'obtient ça. Que dois-je faire ensuite ?
==5939== Memcheck, a memory error detector
==5939== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5939== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==5939== Command: ./PROJET
==5939==
==5939== Invalid write of size 4
==5939== at 0x10A107: airplan_id (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A383: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939== Address 0x4a5217c is 0 bytes after a block of size 12 alloc'd
==5939== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5939== by 0x10A373: add_airplane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x10A501: init_plane (in /home/lunemery/Projet C 2A/PROJET)
==5939== by 0x109558: main (in /home/lunemery/Projet C 2A/PROJET)
==5939==
[...]
Compiler avec les options debug … sinon tu as des adresses au lieu de numéros de lignes …
Ce premier message indique que tu écris sans doute après la fin d'un tableau d'entiers.
Ah oui, t'as raison. J'avais oublié de rajouter -Wall.
J'ai finalement trouvé ce pourquoi il y avait un seg fault. C'était parce que dans la fonction add_landplane(), je n'allouais pas d'espace mémoire pour le nom de la compagnie. Au final, j'ai opté pour une autre méthode qui m'a permis de faire du 3 en 1.
Ma fonction est finalement devenue :
//Ajout d'avions en attente d'atterrissage ou de décollage
landing *add_landplane(landing *land, airplane *mon_avion, char *NOM, int mode)
{
//Allocation mémoire pour l'avion et son mode (atterrissage ou décollage)
landing *NewPlane = malloc(sizeof(*NewPlane));
NewPlane->suivant = NULL;
//Utilisation de carburant() pour générer les horaires
NewPlane->HORAIRE.H = CARBURANT(24);
NewPlane->HORAIRE.M = CARBURANT(60);
int *identifiant = malloc(4 * sizeof(int));
identifiant = airplan_id(identifiant);
NewPlane->avion = mon_avion;
if (mode == 1)
{
NewPlane->MODE = malloc(strlen("TAKEOFF") * sizeof(char));
memcpy(NewPlane->MODE, "TAKEOFF", strlen("TAKEOFF") * sizeof(char));
}
else if (mode == 2)
{
NewPlane->MODE = malloc(strlen("LANDING") * sizeof(char));
memcpy(NewPlane->MODE, "LANDING", strlen("LANDING") * sizeof(char));
}
NewPlane->avion = mon_avion;
if (land == NULL) return NewPlane;
else
{
landing *land_temp = land;
// Recherche du dernier élément de la liste actuelle
while (land_temp->suivant != NULL) land_temp = land_temp->suivant;
// Affectation du nouvel avion à la liste
land_temp->suivant = NewPlane;
}
return land;
}
@White Crow a écrit: Tu ne testes jamais ton code ? C'est quoi un compilateur? Je pensais que la machine devinait ce que je voulais faire. Ha oui, on ne montre pas comment utiliser une boule de cristal dans les cours de programmation. P.S. Non, le Covid-19 n'a pas encore affecté mon cerveau ...
Le Tout est souvent plus grand que la somme de ses parties.
Ah oui, t'as raison. J'avais oublié de rajouter -Wall.
[...]
et -Wextra … et sans doute -g …
Zekeee a écrit:
[...] Il y a t-il des erreurs ?
Tu ne testes jamais ton code ? Et valgrind il te dit quoi quand tu testes ?
Mon code je le teste mais si je vous demande s'il y a des erreurs, c'est parce que je veux avoir votre avis sur la structure du code pour produire une meilleure version si possible. Si je ne testais pas mes codes, je penses que je ne viendrais même pas sur le forum vu que je n'aurais détecté aucune erreur. Excuse-moi mais t'as remarque n'est pas pertinente.
Concernant valgrind, j'apprendrai à l'utiliser mais pour l'instant j'ai encore du mal à comprendre les lignes affichées sur le terminal à l'utilisation de la commande
Il faut d'urgence le restructurer pour éliminer ces gotos vers l'intérieur d'un switch.
Il y a quelques usages raisonnables du goto (qu'on conseille en général d'éliminer complètement), mais ça n'en fait pas partie.
Les emplois raisonnables c'est pour gérer les anomalies (goto en_cas_d_invasion_martienne) ou pour pallier la pauvreté expressive du langage (goto sortie_boucles_xyz).
Et découper en fonctions beaucoup plus petites. Il ne devrait y en avoir aucune qui, à la fois
Bricole explicitement des chainages ou des allocations, ou des fichiers
Affiche ou cause avec l'utilisateur.
Dans un premier paquet : des fonctions qui manipulent la structure de données. Dans un second, le dialogue avec l'utilisateur (Avec appel des fonctions précédentes)
> pour produire la meilleure version possible
Belle ambition, à qui il ne reste plus qu'à fournir les moyens : au boulot tout de suite
- Edité par michelbillaud 1 janvier 2022 à 8:35:42
Est-ce que ton code fonctionne bien correctement à chaque essai? C'est la première chose et la plus impoortante. Tu demandes notre avis. On ne va pas réécrire tout ton code. Je n'ai pas compris tout de suite les system("cat ...") Tu affiches des menus. Personnellement, je les mettrais dans le code, un menu par fonction: Je le ferais avec des tableaux de pointeurs vers des char à peu près comme suit: char *menu[] = { "première ligne", "deuxième ligne", ... "dernière ligne" }; ... nbLignes = sizeof(menu) / sizeof(menu[0]); for(int i=0; i < nbLignes; i++) { // affiche le numéro du choix et son texte. printf("%d. %s\n", i+1, menu[i]); } Si tu peux simplifier le switch du main et ramener dans les fonctions d'affichage les system("clear"); Je n'aime pas les goto, peux-tu procéder autrement? As-tu créé une tète de liste pour toutes tes listes? As-tu un pointeur vers le dernier élément de chaque liste pour insérer plus rapidement à la fin de liste? Quand tu auras fait suffisamment de corrections, tu pourrais poster ton nouveau code.
Le Tout est souvent plus grand que la somme de ses parties.
Ah oui, t'as raison. J'avais oublié de rajouter -Wall.
[...]
et -Wextra … et sans doute -g …
Zekeee a écrit:
[...] Il y a t-il des erreurs ?
Tu ne testes jamais ton code ? Et valgrind il te dit quoi quand tu testes ?
Mon code je le teste mais si je vous demande s'il y a des erreurs, c'est parce que je veux avoir votre avis sur la structure du code pour produire une meilleure version si possible. Si je ne testais pas mes codes, je penses que je ne viendrais même pas sur le forum vu que je n'aurais détecté aucune erreur. Excuse-moi mais t'as remarque n'est pas pertinente.[...]
Dans ce cas ce que tu demandes est une revue de code, ce qu'on fait une fois qu'on a un code fonctionnel.
Dans ce cas si je revois ton code :
le mélange français/anglais n'est pas des plus heureux. Choisis une ou l'autre des langues pour le nommage, pas une fois l'une et une fois l'autre. En général l'anglais passera toujours mieux ;
Sur le bloc des lignes 4-29 : new plane signifie nouvel avion … hors tu t'occupes de créer un nouvel atterrissage … problème de nommage, c'est incohérent ; tout ce bloc devrait être une fonction qui crée une structure de type landing (ou un pointeur sur) c'est quoi toutes ces constantes magiques 24 ? 60 ? 4 ? lignes 12/13 : tu alloues un espace mémoire et tu le remplis dans une fonction … pourquoi ne pas avoir une fonction qui fait tout cela d'un coup ? centraliser les allocations permet de debuger plus facilement … et évite d'avoir à dupliquer du code … mode 1 ou 2 ??? encore des constantes magiques … il faut apprendre à utiliser des enum … les actions en lignes 17/26 sont redondantes et mériteraient une refactorisation (⇒important)
sur le bloc des lignes 30-41 ici on comprend que tu as alloué une nœud de liste que tu vas ajouter dans une liste et tu fais tout ça inline dans ton code : à refactorer d'urgence !
Il sert à quoi le paramètre NOM ?
Pourquoi y a-t-il des identifiants entièrement en majuscules dans ton code ?
Ici ta fonction devrait ressembler un peu plus à quelque chose comme :
Je préfère nommer la sdd liste que tu gères traffic (plus cohérent que landing àmha). Le traffic est composé d'événements (atterrissages et décollages qui seront identifiés via un enum).
Ta fonction se simplifie en une création d'événement suivie d'une insertion dans une liste …
Comme il faut communiquer l'état final des action j'utilise un type (un enum ou autre chose plus complexe) pour dire à l'appelant si l'insertion a ou non réussie.
Ton problème est que tu as sans doute beaucoup avancé dans ton projet sans avoir vraiment essayé de le designer correctement avant … et que si tu dois refactorer ça va te coûter énormément en temps et en en énergie je suppose.
Edit:
Zekeee a écrit:
[...]
Concernant valgrind, j'apprendrai à l'utiliser mais pour l'instant j'ai encore du mal à comprendre les lignes affichées sur le terminal à l'utilisation de la commande
- Edité par Zekeee il y a environ 5 heures
Dis-toi que si tu as des messages avec Valgrind c'est que ton code n'est pas fonctionnel et contient des erreurs …
Poste un extrait pour qu'on voit.
Edit 2 :
Les remarques de Michel sont importantes.
Et l'utilisation du terme «raisonnable» est à prendre aussi bien dans le sens de «convenable» (convient dans certaines situations comme pour les goto) que dans le sens «manipulable pour effectuer un raisonnement» car debuger un code c'est le comprendre et le suivre, et il n'y a pas que l'histoire de debuger, il faut aussi être «raisonnablement» certain que le code est correct.
Rendre un code raisonnable c'est le rendre compréhensible en utilisant un nommage adéquat (une ligne fait ce qu'elle dit faire), ne pas avoir besoin de rajouter des commentaires (si un code n'est pas lisible il ne le sera pas plus en le commentant), …
Avant d'écrire quelque chose d'aussi gros avec les listes chaînées, j'aurais fait de petits tests pour comprendre comment faire. Ensuite on ajoute des éléments nouveaux progressivement. Et on teste le plus possible entre chaque étape.
edit: Pour ajouter un nouvel élément dans une liste, j'aurais séparé les choses comme suit: + appeler une fonction qui génère le nouvel élément * ça suppose que cette fonction appelle une fonction pour demander la mémoire comme ma fonction getArea. + on ajoute l'élément à la liste. On ne peut pas faire une fonction générale pour ajouter tout type d'élément car les structures ne sont pas identiques. Mais en simplifiant le code, c'est plus facile de trouver les erreurs.
- Edité par PierrotLeFou 1 janvier 2022 à 19:22:14
Le Tout est souvent plus grand que la somme de ses parties.
Et la gestion de la mémoire est-elle si importante pour que tu n'alloues pas un octet pour le \0 pour, par exemple, MODE, et que tu fais des memcpy() plutot que des strcpy() ? Si tu penses afficher cette variable MODE avec printf(), ça va poser problème car le \0 ne sera pas présent.
- Edité par edgarjacobs 1 janvier 2022 à 20:20:45
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
En fait quand on regarde de plus près ton code on s'aperçoit rapidement qu'il y a pas mal d'erreurs de conception. avion.h est un fourre-tout qui contient des choses qui n'ont rien à voir avec un «avion». Il me semble aussi qu'il y a une confusion entre un avion et un vol, qu'on se fout un peu du nombre d'avions qu'une compagnie détient quand on gère un aéroport, et que si une compagnie est blacklistée alors c'est une propriété de la compagnie, … Pourquoi y retrouve-t-on des trucs sur le temps (datetime) et le temps (météo) ?
Il y a aussi une confusion entre une liste d'éléments et les éléments …
Je ne sais pas non plus si toutes les infos seront backupées dans un fichier ou une bdd … mais ça à la limite peu importe si on encapsule bien les données.
Il y a beaucoup de choses à revoir avant même de vouloir pondre un code.
Comme ça, les fonctions de dialogue avec l'utilisateur n'ont
à manipuler que des vraies dates
> Date d;
> printf("Date au format jj/mm/aaaa :");
> scanf("%d/%d/%d", &d.jj, &d.mm, &d.aaaa);
qu'elles transmettent à la "base de données en mémoire" pour les enregistrer
> liste_ajouter(&liste, &d);
ou les récupérer
> d = liste_nieme(& liste, 2)`
PS: l'editeur markdown est pourri, pas moyen de mettre des "&" dans des blocs de code.
- Edité par michelbillaud 2 janvier 2022 à 11:06:45
Ajout d'éléments dans une liste chaîné en C
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
En recherche d'emploi.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent