Partage
  • Partager sur Facebook
  • Partager sur Twitter

TP Pendu

c'est moi que je vais pendre ...

Sujet résolu
    27 janvier 2021 à 17:08:00

    Bonjour à tous

    je me remets à jour en C et histoire de bien m'assurer que je n'ai pas de lacune fondamentales, j'ai repris le cours à zéro.

    J'en suis à réaliser le TP du pendu, sauce maison et je suis confronté depuis le début à une erreur en fin d'exécution du process.

    J'utilise Code::Blocks, qui niveau debug ne vaut pas Visual Studio je trouve, mais bon... j'en profite aussi pour me familiariser avec un nouvel environnement.

    J'ai cru comprendre que mon problème venait de l'allocation mémoire (ou plutôt de la désallocation).

    J'ai donc créé un autre projet à côté en ne gardant que le code d'allocation / affichage / désallocation pour me concentrer sur l'essentiel et ai réussi à obtenir un résultat qui ne plante pas...

    J'ai donc transposé ça dans le projet complet d'origine, qui plante toujours...

    Qu'à cela ne tienne, j'ai dupliqué ce projet et supprimé manuellement ce qui devait me ramener vers le projet créé à côté.

    J'ai désormais 2 projets : tests et tests2 dont le contenu est strictement identique :

    Et pourtant, l'un fonctionne :

    et pas l'autre :

    Comme vous l'avez remarqué, niveau compilation je suis reparti de zéro : suppression de tous les fichiers autre que projet, .c, .h (et le fichier .txt ouvert par le programme), puis F9 qui compile et exécute.

    Après ça, j'obtiens ceci dans Winmerge :

    Je peux fournir le code intégral, mais comme vous le voyez c'est le même sur les deux projets...

    Des idées ?

    Merci d'avance pour vos retours

    Raph

    ps. le copier/coller d'image ne fonctionne pas... ça me génère un sujet avec l'avatar à la place des screenshots...

    -
    Edité par raphaelmollon 27 janvier 2021 à 17:14:21

    • Partager sur Facebook
    • Partager sur Twitter
      27 janvier 2021 à 17:12:16

      Salut,

      Tes images ne sont pas passées, utilise plutôt l'édition de code avec le bouton </> (C++).

      Après, il suffit que les options de compilation ne soient pas les mêmes pour que les fichiers obtenus ne soient pas les même non-plus.

      -
      Edité par drx 27 janvier 2021 à 17:14:16

      • Partager sur Facebook
      • Partager sur Twitter

      Bonhomme !! | Jeu de plateforme : Prototype.

        27 janvier 2021 à 17:20:56

        drx a écrit:

        Salut,

        Tes images ne sont pas passées, utilise plutôt l'édition de code avec le bouton </> (C++).

        Après, il suffit que les options de compilation ne soient pas les mêmes pour que les fichiers obtenus ne soient pas les même non-plus.

        -
        Edité par drx il y a 4 minutes


        Salut, merci pour ta réponse rapide.

        J'ai corrigé les images.

        Pour les options de compile, je n'ai rien touché :

        Et bien sûr j'utilise la même version de l'IDE pour ouvrir les deux projets.

        • Partager sur Facebook
        • Partager sur Twitter
          27 janvier 2021 à 17:21:48

          Windows a écrit:

          0xC0000374 : A heap has been corrupted.

          Il y a une erreur dans ton code !

          • Partager sur Facebook
          • Partager sur Twitter
            27 janvier 2021 à 17:23:15

            rouloude a écrit:

            Windows a écrit:

            0xC0000374 : A heap has been corrupted.

            Il y a une erreur dans ton code !


            J'essaie de déterminer quelle est cette erreur. Ce que je ne comprends pas c'est que le code est le même (cf. screenshots)
            • Partager sur Facebook
            • Partager sur Twitter
              27 janvier 2021 à 17:25:06

              Il y a quand même une erreur dans ton code ! Qui ce produit seulement dans certaines circonstances !
              • Partager sur Facebook
              • Partager sur Twitter
                27 janvier 2021 à 17:28:17

                j'ai dupliqué le projet qui fonctionne.... et l'erreur apparaît sur la copie !

                du coup j'ai tout fermé et réouvert le projet qui fonctionnait, fait un clean manuel et recompilé. Il ne fonctionne plus

                Donc la bonne nouvelle c'est que j'ai maintenant 3 codes identiques qui ont le même comportement. C'est déjà pas mal

                Me reste plus qu'à comprendre quelle est l'erreur que j'ai faite.

                le .h :

                #include <stdio.h>
                #include <stdlib.h>
                #include <string.h>
                #include <ctype.h>
                #include <time.h>
                
                #define TRUE            1
                #define FALSE           0
                
                #define ERR_OK          0
                #define ERROR           1
                #define ERR_FILE_OPEN   1000
                #define ERR_ALLOC       2000
                
                #define BUFFER_LENGTH   1024
                
                
                int loadWords(char *filename, char ***wordsArray, int * nbWords);
                int unloadWords(char **wordsArray, int nbWords);
                

                le .c :

                #include "main.h"
                
                int main()
                {
                    char **words = NULL;
                    char wordFile[BUFFER_LENGTH] = "eng_words.txt";
                    int nbWords = 0, ret, i;
                
                    ret = loadWords(wordFile, &words, &nbWords);
                    if (ret != ERR_OK) {
                        printf("Error (%d) while loading file: %s\n", ret, wordFile);
                        exit(ret);
                    }
                
                    /* display the words */
                    for (i=0;i<nbWords;i++) {
                        if (i)  printf(", %s", words[i]);
                        else    printf("List: %s", words[i]);
                    }
                
                    ret = unloadWords(words, nbWords);
                    if (ret != ERR_OK) {
                        printf("Error (%d) while freeing memory", ret);
                        exit(ret);
                    }
                
                    return ERR_OK;
                }
                
                int loadWords(char *filename, char ***wordsArray, int * nbWords) {
                    FILE * file = NULL;
                    char buffer[BUFFER_LENGTH] = "";
                    int nb = 0, i;
                
                    file = fopen(filename, "r");
                    if (file == NULL) return ERR_FILE_OPEN;
                
                    /* first, count the words to allocate the array */
                    while (fgets(buffer, BUFFER_LENGTH, file) != NULL) {
                        nb++;
                    }
                    printf("%d words found\n", nb);
                
                    /* then allocate the array */
                    *wordsArray = malloc(nb * sizeof(char*));
                    if (*wordsArray == NULL) {
                        printf("Allocation error!!\n");
                        exit(ERR_ALLOC);
                    }
                    printf("%d lines'array allocated: %d bytes\n", nb, nb * (int)sizeof(char));
                
                    /* finally read the words again,
                        allocate each cell of the array for the strings and
                        put them in */
                    rewind(file);
                    i = 0;
                    while (fgets(buffer, BUFFER_LENGTH, file) != NULL) {
                        buffer[strlen(buffer)-1] = '\0';
                        (*wordsArray)[i] = malloc(strlen(buffer) * sizeof(char));
                        if ((*wordsArray)[i] == NULL) {
                            printf("Allocation error!!\n");
                            exit(ERR_ALLOC);
                        }
                        strcpy((*wordsArray)[i], buffer);
                        i++;
                    }
                
                    *nbWords = nb;
                
                    fclose(file);
                
                    return ERR_OK;
                }
                
                int unloadWords(char **wordsArray, int nbWords) {
                    int i;
                    for (i=0;i<nbWords;i++) {
                        if (wordsArray[i] != NULL)
                            free(wordsArray[i]);
                    }
                    if (wordsArray != NULL)
                        free(wordsArray);
                
                    return ERR_OK;
                }
                


                le .txt est une suite de mots, à raison d'un mot par ligne

                -
                Edité par raphaelmollon 27 janvier 2021 à 17:34:25

                • Partager sur Facebook
                • Partager sur Twitter
                  27 janvier 2021 à 17:35:04

                  raphaelmollon a écrit:

                  Me reste plus qu'à comprendre quelle est l'erreur que j'ai faite.

                  Tout à fait !

                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 janvier 2021 à 17:39:35

                    Essaies de compiler tes deux codes avec les options -Wall et -Wextra si tu peux le faire (vive les IDE).
                    Si c'est un problème de free(), affiches le pointeur avec le format %p juste après le malloc() et juste avant le free() pour voir si c'est identique.
                    @n'importe qui: existe-til une fonction de comparaison de fichiers sur Windows pour s'assurer que les deux fichiers sont bien identiques?
                    Pas un  ;  de trop en quelque part?
                    • Partager sur Facebook
                    • Partager sur Twitter

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

                      27 janvier 2021 à 17:48:07

                      Ligne 59, tu n'alloues pas suffisamment de mémoire pour loger la chaîne de caractère, tu as oublié la place pour le '\0' de fin de chaîne !

                      avec ce genre d'erreur des fois ça passe des fois ça plante !

                      • Partager sur Facebook
                      • Partager sur Twitter
                        27 janvier 2021 à 18:03:25

                        p*** mais quel boulet je fais !

                        correction :

                                (*wordsArray)[i] = malloc((strlen(buffer)+1) * sizeof(char));
                        


                        Merci !!!

                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 janvier 2021 à 18:32:32

                          L'utilisation de sizeof(char) est inutile car ça vaut toujours 1 et ça allourdit le code.
                          • Partager sur Facebook
                          • Partager sur Twitter

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

                            27 janvier 2021 à 19:06:01

                            PierrotLeFou a écrit:

                            L'utilisation de sizeof(char) est inutile car ça vaut toujours 1 et ça allourdit le code.


                            Je ne suis pas d'accord avec toi. Premièrement ça rappelle ce qu'on est en train d'allouer (des char).

                            Deuxièmement, si la taille du char vient à changer, pour une raison ou une autre, tout code deviendra obsolète.

                            L'alourdissement en question n'est pas fantastique non plus.

                            PierrotLeFou a écrit:

                            @n'importe qui: existe-til une fonction de comparaison de fichiers sur Windows pour s'assurer que les deux fichiers sont bien identiques?

                            Que cherches-tu exactement ? Comparaison de fichiers texte sur Windows ==> Winmerge

                            -
                            Edité par raphaelmollon 27 janvier 2021 à 19:08:14

                            • Partager sur Facebook
                            • Partager sur Twitter
                              27 janvier 2021 à 19:18:16

                              Personne ne recommande d'utiliser sizeof(char), je ne suis pas le seul.
                              Même au temps de C89, voire avant, ça valait toujours 1. Ça n'est pas près de changer.
                              Pour la fonction de comparaison, c'était pour comparer tes deux fichiers que tu disais identiques.
                              Moi, je triche car j'ai Cygwin64 sur mon Windows et je peux utiliser le programme diff de Linux.
                              Heureux de savoir que tu ne te pendras pas. :)
                              • Partager sur Facebook
                              • Partager sur Twitter

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

                                27 janvier 2021 à 19:20:39

                                @PierrotLeFou: oui, il y a comp ou fc -- jamais utilisés. J'ignore la différence entre les deux.

                                Edit: apparemment, fc permet une comparaison binaire, et pas comp

                                @raphaelmolon: si la taille d'un char change un jour, ce ne sera pas sur l'os que tu utilises. Alors autant oublier le sizeof(char), qui alourdit non pas le code (le compilateur s'en moque), mais la lecture du code.

                                -
                                Edité par edgarjacobs 27 janvier 2021 à 19:33:28

                                • 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

                                  27 janvier 2021 à 20:01:15

                                  Le sizeof(char) personnellement, ça ne me gène pas !

                                  edgarjacobs a écrit:

                                  si la taille d'un char change un jour, ce ne sera pas sur l'os que tu utilises. Alors autant oublier le sizeof(char)...

                                  Ça n'a rien à voir avec l'OS !

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    27 janvier 2021 à 20:13:36

                                    @rouloude: tu as raison, désolé pour l'erreur.

                                    -
                                    Edité par edgarjacobs 27 janvier 2021 à 20:19:11

                                    • 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

                                      27 janvier 2021 à 20:36:48

                                      Bah techniquement la «taille» d'un char peut changer, mais par définition sizeof(char) (et signed char et unsigned char) vaudra  toujours 1. La «taille» d'un char, au sens longueur en bit est donné par CHAR_BIT qui vaut au minimum 8 et dépend de l'implémentation.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        27 janvier 2021 à 20:51:31

                                        On a bien sizeof(int) = sizeof(long) aujourd'hui (en tout cas sur mon windaube). J'imagine que ça n'a pas toujours été le cas, sinon aucun intérêt d'avoir deux types. Donc pourquoi pas char

                                        Je confirme que c'est du paluchage de neurones, mais puisque Pierrot nous a lancés sur le sujet :)

                                        Pour le reste, je confirme que pour comparer deux fichiers, beaucoup plus intuitif et ergonomique que diff, Winmerge est une excellente solution et peut même depuis quelques temps comparer jusqu'à 3 fichiers d'un coup.

                                        Et oui, j'ai rangé la corde pour l'instant.

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          27 janvier 2021 à 21:27:39

                                          raphaelmollon a écrit:

                                          On a bien sizeof(int) = sizeof(long) aujourd'hui (en tout cas sur mon windaube). J'imagine que ça n'a pas toujours été le cas, sinon aucun intérêt d'avoir deux types. Donc pourquoi pas char

                                          Je confirme que c'est du paluchage de neurones, mais puisque Pierrot nous a lancés sur le sujet :)

                                          Pour le reste, je confirme que pour comparer deux fichiers, beaucoup plus intuitif et ergonomique que diff, Winmerge est une excellente solution et peut même depuis quelques temps comparer jusqu'à 3 fichiers d'un coup.

                                          Sur les systèmes 16 bits (Windows 3) on avait souvent 8 bits pour les char, 16 bits pour short et int, 32 bits pour long.
                                          Sur les systèmes 32 bits on avait souvent 8 bits pour les char, 16 bits pour short, 32 bits pour int et long.
                                          Sur les systèmes 64 bits on a souvent 8 bits pour les char, 16 bits pour short, 32 bits pour int, 32 ou 64 bits pour long.

                                          Ce que plusieurs personnes ont écrit, mais pas tous les lecteurs ont compris, c'est que sizeof(char) a une valeur fixée par la norme à 1. Ça ne dépend pas de l'implémentation. En langage C, sizeof(char) vaut 1, sinon ce n'est pas du C. C'est pareil en C++ à ma connaissance.

                                          -
                                          Edité par Marc Mongenet 28 janvier 2021 à 1:27:32

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            27 janvier 2021 à 22:57:54

                                            lecture intéressante.

                                            Ceci pourrait mettre tout le monde d'accord : https://stackoverflow.com/questions/7243872/why-write-sizeofchar-if-char-is-1-by-standard

                                            Ce qui donnerait dans le cas de mon code :

                                            (*wordsArray)[i] = malloc((strlen(buffer)+1) * sizeof ***wordsArray);
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              28 janvier 2021 à 1:33:50

                                              raphaelmollon a écrit:

                                              Ceci pourrait mettre tout le monde d'accord : https://stackoverflow.com/questions/7243872/why-write-sizeofchar-if-char-is-1-by-standard

                                              Ce qui donnerait dans le cas de mon code :

                                              (*wordsArray)[i] = malloc((strlen(buffer)+1) * sizeof ***wordsArray);
                                              Oui, utiliser sizeof sur une expression contenant la variable au lieu du type rend le code fiable.

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                28 janvier 2021 à 1:49:21

                                                Le meilleur test est de le faire soi-même sur son système comme j'ai déjà fait.
                                                Pour moi, int et long valent 4 octtets sur un processeur 64-bits. sizeof(long long) vaut 8.
                                                Et sizeof(char *) vaut 8.
                                                J'ai bien trouvé comp et fc sur mon système mais Winmerge n'est pas un produit Windows, je veux dire Microsoft ...
                                                J'irai voir ça de plus près.
                                                • Partager sur Facebook
                                                • Partager sur Twitter

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

                                                  29 janvier 2021 à 0:54:32

                                                  PierrotLeFou a écrit:

                                                  J'ai bien trouvé comp et fc sur mon système mais Winmerge n'est pas un produit Windows, je veux dire Microsoft ...
                                                  J'irai voir ça de plus près.

                                                  C'est encore mieux qu'un produit Microsoft. C'est Open Source. https://winmerge.org
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    29 janvier 2021 à 2:15:37

                                                    Merci pour le lien. Je l'avais déjà trouvé.
                                                    Je suis de plus en plus allergique à Windows.
                                                    J'aime bien les logiciels open-source ...
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

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

                                                      29 janvier 2021 à 10:51:25

                                                      le grand malheur de celui-là c'est qu'il n'existe que pour Windows et sur Linux je n'ai pas encore trouvé d'utilitaire équivalent qui soit aussi agréable à utiliser.

                                                      Il fait partie de mes chouchous avec notepad++

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      TP Pendu

                                                      × 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