Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ajout d'éléments dans une liste chaîné en C

Impossible de rajouter des éléments dans ma liste chaînée

    30 décembre 2021 à 20:53:40

    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);
    
    





    • Partager sur Facebook
    • Partager sur Twitter
      30 décembre 2021 à 21:15:48

      Tu as quand même pas loin de 700 ligne de code, il faudrait tenir compte des warnings !

      • Partager sur Facebook
      • Partager sur Twitter
      ...
        30 décembre 2021 à 21:19:57

        Oui, le truc qui est bien, c'est que j'ai résolu les warnings au fur et à mesure. Pour le coup, j'en ai pas
        • Partager sur Facebook
        • Partager sur Twitter
          30 décembre 2021 à 21:28:18

          Bonjour,

          trop de choses à lire.

          Mais j'ai vu une erreur dans un survol rapide. Tu alloues 3 int pour ton airplan_id, mais tu en remplis 4!

          • Partager sur Facebook
          • Partager sur Twitter

          En recherche d'emploi.

            30 décembre 2021 à 21:57:39

            Pourtant je n'ai pas de soucis avec lors de la lecture, je modifie ça. Le problème se trouve dans le cas 1 de mon switch
            • Partager sur Facebook
            • Partager sur Twitter
              30 décembre 2021 à 22:23:43

              Bonjour,

              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 …

              • Partager sur Facebook
              • Partager sur Twitter
                30 décembre 2021 à 22:38:07

                Je veux bien essayer mais comment je lance le programme en mode débeug sur le terminal linux ?

                -
                Edité par Zekeee 30 décembre 2021 à 22:39:03

                • Partager sur Facebook
                • Partager sur Twitter
                  30 décembre 2021 à 22:51:20

                  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...

                  -
                  Edité par robun 30 décembre 2021 à 22:52:22

                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 décembre 2021 à 23:06:02

                    J'ai essayé avec les printf et apparemment l'erreur se trouve à la ligne 90 du fichier main.c 

                    Quant on fait le premier appel de la fonction, ça passe mais à partir du second appel ça beug

                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 décembre 2021 à 23:25:48

                      Il faut commencer par installer les outils indispensables :

                      • valgrind ;
                      • gdb.

                      Une fois que tu as fais cela, tu compiles ton programme avec les options de debug (tu files l'option -g à clang ou gcc).

                      Puis en console tu lances la commande :

                      valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./ton_programme

                      Et voilà la première étape.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 décembre 2021 à 23:47:20

                        Hello,

                        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

                        • Partager sur Facebook
                        • Partager sur Twitter

                        On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                          31 décembre 2021 à 0:48:30

                          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== 
                          
                          
                          



                          • Partager sur Facebook
                          • Partager sur Twitter
                            31 décembre 2021 à 0:55:26

                            Zekeee a écrit:

                            Le malloc, c'était un test que je faisais, je l'ai retiré du code.

                            Peut-être, mais dans le code présenté, il est toujours présent. J'ai passé du temps pour rien....

                            Zekeee a écrit:

                            DU coup, j'ai fait la première étape avec valgrind et j'obtient ça. Que dois-je faire ensuite ?

                            Apprendre vraiment le C ?
                            • Partager sur Facebook
                            • Partager sur Twitter

                            On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                              31 décembre 2021 à 7:30:43

                              Zekeee a écrit:

                              [...]

                               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.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                31 décembre 2021 à 13:55:28

                                Zekeee a écrit:

                                J'ai essayé avec les printf et apparemment l'erreur se trouve à la ligne 90 du fichier main.c 

                                Quant on fait le premier appel de la fonction, ça passe mais à partir du second appel ça beug


                                Il faut donc mettre des printf dans la fonction.

                                (Mais continue bien sûr avec Valgrind. Je donnais cette méthode au cas où.)

                                -
                                Edité par robun 31 décembre 2021 à 13:57:32

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  31 décembre 2021 à 14:11:24

                                  Zekeee a écrit:

                                  Oui, le truc qui est bien, c'est que j'ai résolu les warnings au fur et à mesure. Pour le coup, j'en ai pas

                                  Ah oui ?  J'ai essayé de compiler ton code, j'en ai une tabassée !

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  ...
                                    31 décembre 2021 à 20:03:16

                                    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;
                                    }

                                     Il y a t-il des erreurs ?

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      31 décembre 2021 à 21:03:07

                                      Tu sembles ajouter à la fin de la liste assez souvent.
                                      Pourquoi ne pas ajouter un pointeur vers le dernier de la liste dans le descripteur de liste?

                                      -
                                      Edité par PierrotLeFou 31 décembre 2021 à 21:04:35

                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Le Tout est souvent plus grand que la somme de ses parties.

                                        31 décembre 2021 à 22:10:55

                                        Zekeee a écrit:

                                        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 ?

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          1 janvier 2022 à 2:16:48

                                          @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 ...
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Le Tout est souvent plus grand que la somme de ses parties.

                                            1 janvier 2022 à 7:14:02

                                            White Crow a écrit:

                                            Zekeee a écrit:

                                            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

                                            -
                                            Edité par Zekeee 1 janvier 2022 à 7:15:23

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              1 janvier 2022 à 8:05:54

                                              > votre avis sur la structure du code

                                              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

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                1 janvier 2022 à 8:34:18

                                                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.
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Le Tout est souvent plus grand que la somme de ses parties.

                                                  1 janvier 2022 à 12:38:13

                                                  Zekeee a écrit:

                                                  White Crow a écrit:

                                                  Zekeee a écrit:

                                                  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 :

                                                  traffic_status traffic_add_event(traffic *traffic, airplane *airplane, enum mode mode)
                                                  {
                                                      traffic_event *event=traffic_event_new(airplane, mode);
                                                      if (event)
                                                          return traffic_append(traffic, event);
                                                      else
                                                          return TRAFFIC_STATUS_FAIL;
                                                  }

                                                  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), …

                                                  C'est hyper important.

                                                  -
                                                  Edité par White Crow 1 janvier 2022 à 12:53:05

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    1 janvier 2022 à 17:56:46

                                                    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

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

                                                    Le Tout est souvent plus grand que la somme de ses parties.

                                                      1 janvier 2022 à 20:19:52

                                                      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

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                                        1 janvier 2022 à 23:56:01

                                                        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.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          2 janvier 2022 à 10:49:13

                                                          Un peu plus tôt je parlais de la séparation à faire entre

                                                          • actions de manipulation de la "base de données"
                                                          • dialogue avec l'utilisateur.

                                                          Ca m'a fait penser à un défaut de conception extrêmement fréquent dans les exercices sur les listes chaînées.

                                                          (Qui s'ajoute au truc habituel de confondre liste et adresse du premier maillon).

                                                          Mauvaise idée

                                                          Exemple, on veut manipuler une liste de dates.

                                                          Alors on se précipite à définir le type

                                                          struct Date {
                                                          	int jj, mm, aaaa;
                                                          	struct Date *suivante, *precedente;
                                                          };
                                                          
                                                          struct Liste_Dates {
                                                          	struct Date *premiere, *dernière;
                                                          };
                                                          

                                                          avec des chaînages internes à la structure Date.

                                                          Conséquences néfastes

                                                          • les fonctions de saisie se retrouvent à manipuler une structure avec des champs de chaînage dont elles n'ont rien à battre ;
                                                          • les dates ainsi définies ne sont pas utilisables pour autre chose.

                                                          Une meilleure approche

                                                          Séparer la notion de valeur (date) et la notion de collection. En soi, une date n'a aucun attribut qui en fasse un morceau de liste.

                                                          Donc, on fait un chaînage externe à la structure qui représente la valeur :

                                                          struct Date {
                                                          	int jj, mm, aaaa;
                                                          };
                                                          

                                                          et pour en faire des listes, on définit un type Maillon_Date qui contient une date.

                                                          struct Maillon_Date {
                                                          	struct Date date;
                                                          	struct Maillon_Date *precedent, *suivant;
                                                          };
                                                          
                                                          struct Liste_Date {
                                                          	struct Maillon_Date *premier, *dernier;
                                                          	int taille;
                                                          };
                                                          

                                                          Usage

                                                          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

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

                                                          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.
                                                          • Editeur
                                                          • Markdown