Partage
  • Partager sur Facebook
  • Partager sur Twitter

Taille tableau +1...

... je n'y arrive pas.

Sujet résolu
    19 janvier 2007 à 11:53:44

    Bonjour,

    pour me familiariser avec 'malloc()', j'ai fait ce code (qui fonctionne... :) ) :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    //------------------------------------------------------------------------------
    //                  STRUCTURE(S)...
    //------------------------------------------------------------------------------

    typedef struct Equipe
    {
        char nom[20];
        long score;
    }
    Equipe;

    //------------------------------------------------------------------------------
    //                    Fonction Principale (main)...
    //------------------------------------------------------------------------------
    int main(void)
    {

        int i = 0;

        int memTampon = 0;
        int place = 1;
        int nombreDeTeam = 0;

        char nomTampon[20] ="";

    //------------------------------------------------------------------------------

        // Allocation du nombre de teams...
        printf("\n Combien de TEAMS ? ");
        scanf("%d", &nombreDeTeam);

    //------------------------------------------------------------------------------
        Equipe *team = malloc(nombreDeTeam * sizeof *team);
        if (team != NULL) // si allocation réussie...
        {
            // Saisie des infos concernant chaque team...
            for (i = 0 ; i < nombreDeTeam; i++)
            {
                printf("\n Nom de la TEAM -%d- : ", i+1);
                scanf ("%s", team[i].nom);

                printf(" Votre score : ");
                scanf ("%ld", &team[i].score);
            }
        }

        else // si allocation échouée...
        exit(0);

        // Classement du tableau par ordre décroissants des scores
        for (i = 0 ; i < (nombreDeTeam - 1) ; i++)
        {

            if (team[i].score == team[i+1].score);

            else
            {

                while (team[i].score < team[i+1].score)
                {

                    memTampon = team[i].score;
                    strcpy(nomTampon, team[i].nom);

                    team[i].score = team[i+1].score;
                    strcpy(team[i].nom, team[i+1].nom);

                    team[i+1].score = memTampon;
                    strcpy(team[i+1].nom, nomTampon);

                    i = 0;

                }

            }

        }

        // affichage des scores...
        for (i = 0 ; i < nombreDeTeam; i++)
        {
            printf("\n %d -> %s = SCORE : %ld \n", place, team[i].nom, team[i].score);
            place++;
        }

        free(team);

    //------------------------------------------------------------------------------
    //                    FIN DU PROG...
    //------------------------------------------------------------------------------
        return 0;
    }



    Je voulais ensuite que le programme ne demande plus le nombre de teams à l'avance, mais ajouter une team à chaque fois dans un tableau augmentant sa taille au fur et à mesure, alors j'ai voulu essayer comme celà (... et ça ne marche pas... :( ) :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    //------------------------------------------------------------------------------
    //                  STRUCTURE(S)...
    //------------------------------------------------------------------------------

    typedef struct Equipe
    {
        char nom[20];
        long score;
    }
    Equipe;

    //------------------------------------------------------------------------------
    //                    Fonction Principale (main)...
    //------------------------------------------------------------------------------
    int main(void)
    {

        int i = 0;
        int quitter = 0;
        int choix = 0;
        int memTampon = 0;
        int place = 1;
        int nTeam = 1;

        int nombreDeTeam = 1;

        char nomTampon[20] ="";

        Equipe *team = NULL;
        Equipe *team_bis = NULL;

    //------------------------------------------------------------------------------

        team = malloc(nombreDeTeam * sizeof(int));
        if (team == NULL) // Si l'allocation a échoué
        {
            printf("\n\n Echec d'allocation...");
            system("PAUSE");
            exit(0); // On arrête immédiatement le programme
        }
        do
        {
            printf("\n\n Nom de la TEAM -%d- ", nTeam);
            scanf ("%s", team[i].nom);

            printf(" son Score = ");
            scanf ("%ld", &team[i].score);

            //menu...

            printf("\n\n\t -> MENU <- \n"
                   "\n 1.Continuer  -  3.Quitter\n\n"
                   "   Votre choix = ");
            scanf ("%d", &choix);

            switch(choix)
            {
    //------------------------------------------------------------------------------
                // Ajouter une Team...
                case 1:

                nombreDeTeam++;

                team_bis=malloc(nombreDeTeam * sizeof(int));
                if (team_bis == NULL) // Si l'allocation a échoué
                {
                printf("\n\n Echec d'allocation...");
                system("PAUSE");
                exit(0); // On arrête immédiatement le programme
                }

                for (i = 0 ; i < nombreDeTeam ; i++)
                {
                    team_bis[i].score = team[i].score;
                    strcpy(team_bis[i].nom, team[i].nom);
                }

                free(team);

                team = malloc(nombreDeTeam * sizeof(int));
                if (team == NULL) // Si l'allocation a échoué
                {
                printf("\n\n Echec d'allocation...");
                system("PAUSE");
                exit(0); // On arrête immédiatement le programme
                }

                for (i = 0 ; i < nombreDeTeam ; i++)
                {
                    team[i].score = team_bis[i].score;
                    strcpy(team[i].nom, team_bis[i].nom);
                }

                free(team_bis);

                i = nombreDeTeam;
                nTeam++;

    //------------------------------------------------------------------------------
                if (nombreDeTeam > 2)
                {
                    // Classement du tableau par ordre décroissants des scores
                    for (i = 0 ; i < (nombreDeTeam - 1) ; i++)
                    {
                        if (team[i].score == team[i+1].score);

                        else
                        {
                            while (team[i].score < team[i+1].score)
                            {
                                memTampon = team[i].score;
                                strcpy(nomTampon, team[i].nom);

                                team[i].score = team[i+1].score;
                                strcpy(team[i].nom, team[i+1].nom);

                                team[i+1].score = memTampon;
                                strcpy(team[i+1].nom, nomTampon);

                                i = 0;
                            }
                        }
                    }

                    // affichage des scores...
                    for (i = 0 ; i < nombreDeTeam ; i++)
                    {
                        printf("\n %d -> %s = SCORE : %ld \n", place, team[i].nom, team[i].score);
                        place++;
                    }
                }
                quitter = 0;
                break;

    //------------------------------------------------------------------------------
                // Quitter...
                case 3 :
                free(team);
                free(team_bis);
                quitter = 1;
                printf("\n Au Revoir !");
                break;

                default:
                quitter = 0;
                break;
            }
        }
        while (!quitter);

    //------------------------------------------------------------------------------
    //                    FIN DU PROG...
    //------------------------------------------------------------------------------
        return 0;
    }

    ...et j'aimerai comprendre pourquoi.

    Merci d'avance pour vos réponses.
    • Partager sur Facebook
    • Partager sur Twitter
      19 janvier 2007 à 12:36:46

      Citation : AymLeGrand

      Pour me familiariser avec 'malloc()', j'ai fait ce code (qui fonctionne... :) ) :


      Euh, non. Il ne fonctionne pas. (Comportement indéterminé).

      Citation : Pas de titre



      typedef struct Equipe
      {
          char nom[20];
          long score;
      }
      Equipe;

          Equipe *team = NULL;
          Equipe *team_bis = NULL;

          team = malloc(nombreDeTeam * sizeof(int));


      pourquoi sizeof (int) ?
          Equipe *team = malloc(nombreDeTeam * sizeof *team);

      tout simplement...

      http://mapage.noos.fr/emdel/notes.htm#malloc

      Ensuite, attention, malloc() peut échouer... Il faut tester la valeur retournée avant de l'utiliser...
         if (team != NULL)
         {

      Penser aussi à libérer après usage...
      • Partager sur Facebook
      • Partager sur Twitter
      Music only !
        19 janvier 2007 à 13:16:14

        Merci -ed-,

        J'ai réédité le premier code selon tes conseils et il fonctionne ... (comme avant :o)
        Qu'entends-tu par comportment indéterminé alors ?

        Citation : -ed-

        pourquoi sizeof (int) ?


        ... désolé, je n'avais pas fais gaffe, je m'emmêle encore un peu les pinceaux avec les pointeurs :-°

        Merci de ton lien, j'y ai découvert l'existence d'une fonction 'realloc()' qui, il me semble, résoudrait le problème de mon deuxième code (enfin... une fois que j'aurai compris son fonctionnement).

        J'y regarderai de plus près dans la soirée car là je n'en ai plus le temps (je pars bosser).


        • Partager sur Facebook
        • Partager sur Twitter
          19 janvier 2007 à 14:37:41

          Citation : AymLeGrand

          Merci -ed-,

          J'ai réédité le premier code selon tes conseils et il fonctionne ... (comme avant :o)
          Qu'entends-tu par comportment indéterminé alors ?

          Citation : -ed-

          pourquoi sizeof (int) ?


          ... désolé, je n'avais pas fais gaffe, je m'emmêle encore un peu les pinceaux avec les pointeurs :-°

          Merci de ton lien, j'y ai découvert l'existence d'une fonction 'realloc()' qui, il me semble, résoudrait le problème de mon deuxième code (enfin... une fois que j'aurai compris son fonctionnement).

          J'y regarderai de plus près dans la soirée car là je n'en ai plus le temps (je pars bosser).



          Un comportement indéfini est un comportement qui n'est pas prévu par la norme. Tout peut se passer. L'application peut crasher, le pc peut redémarrer, on peut écrire sur les données systèmes... ou ça peut marcher comme si de rien était jusqu'au jour ou ça va plus marcher :)
          • Partager sur Facebook
          • Partager sur Twitter
            19 janvier 2007 à 14:41:17

            ecrire sur les données systèmes ...

            Rien de tel sous linux. Ce 'privilège' est réservé aux 'heureux' utilisateurs de Windows ^^
            • Partager sur Facebook
            • Partager sur Twitter
              19 janvier 2007 à 14:56:54

              Citation : Darkelfe

              ecrire sur les données systèmes ...

              Rien de tel sous linux. Ce 'privilège' est réservé aux 'heureux' utilisateurs de Windows ^^


              Ai-je parlé de linux ? de windows ?
              Je n'ai fait que présenter certaines manifestation de comportement indéfini. Il en existe beaucoup d'autres ...
              • Partager sur Facebook
              • Partager sur Twitter
                19 janvier 2007 à 15:50:20

                Citation : AymLeGrand

                J'ai réédité le premier code selon tes conseils et il fonctionne ... (comme avant :o)
                Qu'entends-tu par comportment indéterminé alors ?


                http://mapage.noos.fr/emdel/notes.htm#ub
                • Partager sur Facebook
                • Partager sur Twitter
                Music only !
                  19 janvier 2007 à 17:36:25

                  asmanur, je sais.

                  Moi, je me suis contenté de commenter de ce que tu avit dit et de faire un peu de pub pour linux, c'est tout.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 janvier 2007 à 18:45:17

                    Citation : Darkelfe

                    ecrire sur les données systèmes ...

                    Rien de tel sous linux. Ce 'privilège' est réservé aux 'heureux' utilisateurs de Windows ^^


                    Troll Alert

                    Ce n'est pas le système qui empêche le programmeur de faire n'importe quoi.

                    Ceci-dit, les conséquences d'une tentative d'écriture en mémoire protégée se traduit sous Unixoïde comme sous Windows NT (XP etc.) par une exception et les données ne sont pas modifiées.

                    Pour DOS/Windows 9x/2k, je ne suis as sûr que la protection fonctionne aussi bien. Pour MS-DOS, elle ne fonctionne pas du tout (sauf peut être en mode étendu par DPMI, comme Windows 3.x, mais c'est vieux, je ne m'en souviens plus et j'ai peu pratiqué).
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Music only !
                      19 janvier 2007 à 23:33:30

                      A l'-eeeeeed- :lol:

                      J'ai essayé la fonction 'realloc()' en tentant de suivre le modèle de ton lien et force est de constater que... je n'ai pas TOUT compris...

                      Malgré ceci :
                      Project   : Console application
                      Compiler  : GNU GCC Compiler (called directly)
                      Directory : C:\CodeBlocks_PROGZ\NEW\
                      --------------------------------------------------------------------------------
                      Switching to target: default
                      Compiling: main.c
                      Linking console executable: C:\CodeBlocks_PROGZ\NEW\console.exe
                      Process terminated with status 0 (0 minutes, 0 seconds)
                      0 errors, 0 warnings

                      Il fonctionne de façon très bizarre, ... comportement indéterminé ?!?

                      Voici le code en question (Force +++ sur l'échelle du goret o_O ) :

                      #include <stdio.h>
                      #include <stdlib.h>
                      #include <string.h>

                      //------------------------------------------------------------------------------
                      //                  STRUCTURE(S)...
                      //------------------------------------------------------------------------------

                      typedef struct Equipe
                      {
                          char nom[20];
                          long score;
                      }
                      Equipe;

                      //------------------------------------------------------------------------------
                      //                    Fonction Principale (main)...
                      //------------------------------------------------------------------------------
                      int main(void)
                      {

                          int i = 0;
                          int quitter = 0;
                          int choix = 0;
                          int memTampon = 0;
                          int place = 1;
                          int nTeam = 1;

                          int nombreDeTeam = 0;

                          char nomTampon[20] ="";

                      //------------------------------------------------------------------------------

                          Equipe *team = malloc(nombreDeTeam * sizeof(team));
                          if (team == NULL) // Si l'allocation a échoué
                          {
                              printf("\n\n Echec d'allocation...");
                              system("PAUSE");
                              exit(0); // On arrête immédiatement le programme
                          }

                          do
                          {
                              printf("\n\n Nom de la TEAM -%d- ", nTeam);
                              scanf ("%s", team[i].nom);

                              printf(" son Score = ");
                              scanf ("%ld", &team[i].score);

                              //menu...
                              printf("\n\n\t -> MENU <- \n"
                                     "\n 1.Continuer  -  3.Quitter\n\n"
                                     "   Votre choix = ");
                              scanf ("%d", &choix);

                              switch(choix)
                              {
                      //------------------------------------------------------------------------------
                                  // Ajouter une Team...
                                  case 1:

                                  nombreDeTeam++;

                                  Equipe *team_tampon = realloc(team, nombreDeTeam * sizeof(team_tampon));

                                  if (team_tampon != NULL)
                                  {

                                      for (i = 0 ; i < nombreDeTeam ; i++)
                                      {
                                          team_tampon[i].score = team[i].score;
                                          strcpy(team_tampon[i].nom, team[i].nom);
                                      }

                                      team = team_tampon;

                                      for (i = 0 ; i < nombreDeTeam ; i++)
                                      {
                                          team[i].score = team_tampon[i].score;
                                          strcpy(team[i].nom, team_tampon[i].nom);
                                      }

                                  }

                                  else
                                  {
                                      printf("\n Ajout de TEAM impossible, veuillez quitter ce programme !");
                                  }

                                  nTeam++;

                      //------------------------------------------------------------------------------

                                  if (nombreDeTeam >= 2)
                                  {
                                      // Classement du tableau par ordre décroissants des scores
                                      for (i = 0 ; i < (nombreDeTeam - 1) ; i++)
                                      {
                                          if (team[i].score == team[i+1].score)
                                              ;

                                          else
                                          {
                                              while (team[i].score < team[i+1].score)
                                              {
                                                  memTampon = team[i].score;
                                                  strcpy(nomTampon, team[i].nom);

                                                  team[i].score = team[i+1].score;
                                                  strcpy(team[i].nom, team[i+1].nom);

                                                  team[i+1].score = memTampon;
                                                  strcpy(team[i+1].nom, nomTampon);

                                                  i = 0;
                                              }
                                          }
                                      }

                                      // affichage des scores...
                                      place = 1;
                                      for (i = 0 ; i < nombreDeTeam ; i++)
                                      {
                                          printf("\n %d -> %s = SCORE : %ld ", place, team[i].nom, team[i].score);
                                          place++;
                                      }
                                  }

                                  quitter = 0;
                                  break;

                      //------------------------------------------------------------------------------

                                  // Quitter...
                                  case 3 :
                                  free(team);
                                  free(team_tampon);
                                  quitter = 1;
                                  printf("\n Au Revoir !");
                                  break;

                                  default:
                                  quitter = 0;
                                  break;
                              }
                          }
                          while (!quitter);

                      //------------------------------------------------------------------------------
                      //                    FIN DU PROG...
                      //------------------------------------------------------------------------------
                          return 0;
                      }


                      Encore merci de m'éclaircir certains points et de pointer mes erreurs.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        19 janvier 2007 à 23:41:15

                        Citation : AymLeGrand


                        Il fonctionne de façon très bizarre, ... comportement indéterminé ?!?

                        Voici le code en question (Force +++ sur l'échelle du goret o_O ) :


                        Si il s'agit d'apprendre à maitriser realloc(), ca fait beaucoup trop de lignes de codes.

                        Je conseille (euphemism inside) de travailler sur un tout petit programme qui ne traite qu'un problème à la fois et est le plus dépouillé possible.

                        J'ai commencé à regarder ton code. Visiblement, tu as mal lu mon article. Pour l'allocation, la formue générique est
                           T *p = malloc (sizeof *p * n);

                        or tu as codé

                        Citation : Pas de titre

                           Equipe *team = malloc (nombreDeTeam * sizeof (team));

                        • Des parenthèses en trop
                        • Manque une *

                        Même horrible bug dans le realloc()

                        Est-ce que j'ai dit quelque part qu'il fallait recopier quelque chose après un realloc() (à part la valeur du nouveau pointeur, bien sûr)? Dans le doute, as-tu lu la doc de realloc() ?

                        Ensuite, dans le swap du tri, il suffit d'utiliser l'opérateur d'affectation (=) pour copier une structure d'un coup si elle est linéaire (c'est la cas ici : pas de pointeurs dans la structure).
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Music only !
                          20 janvier 2007 à 0:14:55

                          Citation : -ed-

                          Est-ce que j'ai dit quelque part qu'il fallait recopier quelque chose après un realloc() ?


                          ... non, c'est vrai, je crois que j'ai trop focalisé sur le raisonnement de mon ancien code...

                          Citation : -ed-

                          [...](euphemism inside)[...]


                          ... A mon niveau, c'est déjà un projet AMBITIEUX étant donné le temps qu'il m'a pris la tête avant de l'écrire (lol)

                          Citation : -ed-

                          [...]dans le swap du tri, il suffit d'utiliser = pour copier une structure d'un coup[...]


                          ... tout con en fait, mais merci, je ne l'aurais même pas osé !

                          Citation : -ed-

                          Des parenthèses en trop
                          Manque une *


                          Oups, je mélange toutes les façons de faire... je comprend mieux pourquoi celà ne fonctionne pas !

                          Merci à toi, je retourne à mon code un plus 'petit' code (et relire ton lien au passage) et, cette fois, j'espère bien en venir à bout...

                          PS : Tu devrais être le complément OFFICIEL du site du zéro !
                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 janvier 2007 à 0:16:26

                            Citation : AymLeGrand

                            PS : Tu devrais être le complément OFFICIEL du site du zéro !


                            A 1000€ la journée ? Trop cher pour eux...
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Music only !
                              22 janvier 2007 à 22:04:09

                              Citation : [...]

                              Je voulais ensuite que le programme ne demande plus le nombre de teams à l'avance, mais ajouter une team à chaque fois dans un tableau augmentant sa taille au fur et à mesure, alors j'ai voulu essayer comme celà (... et ça ne marche pas... :( ) :



                              Maintenant, SI !

                              Grâce aux nombreuses explications d' -ed- et à ces 2 liens (ici et ) j'ai enfin réussi à écrire ce code...

                              #include <stdio.h>
                              #include <stdlib.h>
                              #include <string.h>

                              // STRUCTURE(S)...
                              typedef struct Equipe
                              {
                                  char nom[20];
                                  long score;
                              }
                              Equipe;

                              // FONCTION PRINCIPALE (main)...
                              int main(void)
                              {

                                  int i = 0;
                                  int choix = 1;
                                  int quitter = 0;
                                  int place = 1;
                                  int nombreDeTeams = 0;

                                  Equipe *team = malloc(nombreDeTeams * sizeof *team);
                                  if (team == NULL)
                                  {
                                      printf("\n Allocation echouee...\n");
                                      exit(0);
                                  }

                                  Equipe *team_tampon = malloc(1 * sizeof *team_tampon);
                                  if (team_tampon == NULL)
                                  {
                                      printf("\n Allocation echouee...\n");
                                      exit(0);
                                  }

                                  do
                                  {
                                      // Classer le tableau par ordre décroissant des scores...
                                      if (nombreDeTeams >= 2)
                                      {
                                          for (i = 0 ; i < (nombreDeTeams - 1) ; i++)
                                          {
                                              if (team[i].score == team[i+1].score);

                                              else
                                              {
                                                  while (team[i].score < team[i+1].score)
                                                  {
                                                      team_tampon[0] = team[i];
                                                      team[i] = team[i+1];
                                                      team[i+1] = team_tampon[0];
                                                      i = 0;
                                                  }
                                              }
                                          }

                                          // Afficher le tableau...
                                          place = 1;
                                          printf("\n #>> CLASSEMENT <<# \n");
                                          for (i = 0 ; i < nombreDeTeams ; i++)
                                          {
                                              printf("\n %d -> %s - - - %ld points ", place, team[i].nom, team[i].score);
                                              fflush (stdout);
                                              place++;
                                          }
                                          printf("\n\n");
                                      }

                                      switch (choix)
                                      {
                                          //
                                          case 1:
                                          // Ajouter une Team...
                                          nombreDeTeams++;
                                          Equipe *team_temporaire = realloc(team, nombreDeTeams * sizeof *team_temporaire);
                                          if (team_temporaire == NULL)
                                          {
                                              printf("\n Re-Allocation echouee...\n");
                                              exit(0);
                                          }
                                          team = team_temporaire;

                                          // Saisir les donnees...
                                          i = (nombreDeTeams - 1);
                                          printf("\n -> TEAM # %d \n"\
                                                 "\n Nom   : ", i+1);
                                          fflush (stdout);
                                          scanf ("%s", team[i].nom);

                                          printf("\n Score : ");
                                          fflush (stdout);
                                          scanf ("%ld", &team[i].score);

                                          // Menu...
                                          printf("\n\n\t\t 1.Continuer  -  2.Quitter \n\n\t\t      Votre choix : ");
                                          fflush (stdout);
                                          scanf ("%d", &choix);
                                          system("CLS");
                                          quitter = 0;
                                          break;

                                          //
                                          case 2:
                                          // Quitter le prog...
                                          printf("\n Au Revoir ! \n");
                                          quitter = 1;
                                          break;
                                      }
                                  }
                                  while (!quitter);

                                  free(team);
                              // FIN DU PROG...
                                  return 0;
                              }


                              ... duquel j'obtiens le comportement attendu.

                              Reste à sécuriser les saisies...

                              Merci asmanur, Darkelfe et -ed-, sans vous, je n'aurai pu clore ce topic ;) !

                              EDIT = 2 variables supprimées du code...
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Taille tableau +1...

                              × 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