IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

erreur incompréhensible


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Inscrit en
    Décembre 2005
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 8
    Par défaut erreur incompréhensible
    salut tout le monde

    j'ai vu sur un forum un ptit jeu, et j'ai voulu le retranscrire en C.

    je vous fais un c/c de l'explication


    record de la plus grande suite de nombre en partant que d'un chiffre : le 0!

    0
    1 0
    1 1 1 0
    3 1 1 0
    1 3 2 1 1 0
    1 1 1 3 1 2 2 1 1 0
    .....


    Pour comprendre c'est pas bien compliqué, il suffit de lire :

    Premiere ligne :
    0
    Vous lisez quoi ? Y a 1 zéro ...
    Donc ligne suivante :
    1 0 (traduction : 1 zéro)
    Vous lisez quoi ? Y a 1 un et 1 zéro ...
    Donc la ligne suivante donne
    1 1 1 0 (traduction : 1 un 1 zéro)
    Vous lisez quoi ? Y a 3 un et 1 zéro ...
    Donc la ligne suivante donne
    3 1 1 0 (traduction : 3 un 1 zéro)

    mon programme marche parfaitement jusqu'au rang 7, mais à partir de 8 il commence a déconner, et me sort une erreur que j'ai pas pu débugger (c'est du code assembleur)

    voila mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef unsigned short mtypeL;
    typedef unsigned char mtypeS;
     
    // estimation de la taille necessaire pour stocker la chaine suivante
    mtypeL compter(mtypeS *ch, mtypeL ln)       
    {
       mtypeL l=1, i=0;
       mtypeS c=ch[0];
     
       while (++i<ln)
       	if ( c!=ch[i] )
            {
          	   c = ch[i];
               l++;
             }
     
       return 2*l;
    }
     
    // Lis la chaine src et stock le resultat dans *dest
    void traiter(mtypeS *src, mtypeS **dest)
    {
       mtypeL lgs=0,lgd,i,j;
       mtypeS c,k;    
     
       while (src[lgs++])
       {}
     
       lgd=compter(src,lgs);
     
       free(*dest);
       *dest=NULL;
     
       if ( (*dest=malloc(lgd*sizeof(mtypeS)))==NULL )
       	return;
     
       for (i=1,c=src[0],k=1,j=0; i<lgd; k++,i++)
           if ( src[i]!=c )
           {
           	    (*dest)[j++]=k;
                (*dest)[j++]=c;
                c=src[i];
                k=0;
           }         
     
       (*dest)[j++]=1;
       (*dest)[j]=0;
    }
     
    // Itere le traitement jusqu'a atteindre le rang souhaité
    void trouver(mtypeL n)
    {
       mtypeS *t[2]={0},i;
     
       t[0]=malloc(sizeof(mtypeS));
     
       t[0][0]=0;
     
       for (i=1; i<n; i++)
       {
    	traiter(t[(i+1)%2],t+i%2);
             if ( t[i%2] == NULL)
             {
          	    printf("ERREUR\n");
                 return;
             }
       }
     
       i=0;n--;
     
       do
       	printf("%d ",t[n%2][i]);
       while ( t[n%2][i++] );
    }
     
    int main(void)
    {
       trouver(8);
       getchar();
       return(0);
    }
    si vous avez une idée d'où l'erreur peut provenir ^^

    c'est mon premier sujet créé sur ce forum, donc sorry si j'ai fait une gaffe.

    merci d'avance

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kasaweb
    si vous avez une idée d'où l'erreur peut provenir
    • <malloc.h> n'est pas standard. C'est <stdlib.h>
    • main() retourne int. Toujours.
    • Un paramètre ne peut faire moins d'un int de large. Inutile de définir des paramètres de type char ou short... Le code de conversion ne fait qu'alourdir et ralentir le programme...
    • Le cast de malloc() est inutile.
    • malloc() peut echouer
    • Dans traiter(), il y a un ; après le while(). C'est normal (il est préférable de mettre les {], c'est plus clair, même si elles sont vides.)

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    • Un paramètre ne peut faire moins d'un int de large. Inutile de définir des paramètres de type char ou short...
    Ca je le savais pas tiens, pourquoi cela ? Donc inutile d'avoir des arguments qui tiennent parfois sur des char, dommage même vu que c'est le type le plus petit, il devrait pouvoir être pris en charge en tant qu'argument !

    Tu peut expliquer ?
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par CSoldier
    Ca je le savais pas tiens, pourquoi cela ? Donc inutile d'avoir des arguments qui tiennent parfois sur des char, dommage même vu que c'est le type le plus petit, il devrait pouvoir être pris en charge en tant qu'argument !

    Tu peut expliquer ?
    les paramètres de type char et short sont automatiquement promus en int. Un paramètre fait donc au minimum un int... Si on passe un char, il est converti en int (perte de temps et code inutile...)

    De même qu'en C90 un float est promu en double. Donc inutile de mettre des paramèttres de type float. (Ca a changer en C99, puis qu'il existe maintenant des fonctions spécifiques pour le floats ).

  5. #5
    Membre averti Avatar de Menthe_a_l_eau
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Par défaut
    Citation Envoyé par CSoldier
    Ca je le savais pas tiens, pourquoi cela ? Donc inutile d'avoir des arguments qui tiennent parfois sur des char, dommage même vu que c'est le type le plus petit, il devrait pouvoir être pris en charge en tant qu'argument !

    Tu peut expliquer ?
    Même sur du microcontrolleur ????

  6. #6
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Citation Envoyé par Menthe_a_l_eau
    Même sur du microcontrolleur ????
    Il faudrait regardé la doc de ton microcontrôleur, de ton compilateur et regarder le code assembleur généré par celui-ci. Sur Motorola 68HC11 (un dinausore 8 bits) les arguments entiers sont passés par un registre 16 bits, qu'il soit short ou même char. Donc la réponse est oui sur cette cible.

    Idem pour les microcontrôleurs Texas Instruments MSP430, les entiers du char au short passent par un registre 16 bits, les long et les floats par 2 registres 16 bits, donc 32 bits. Généralement le type double sur micro à la même magnitude que les float.

    Sur Microchip, il faudrait que je regarde mais ces compilateurs (Motorola, Texas, Microchip) se disent full "ANSI C89" donc je suis quasiment sur que c'est la même chose.

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Menthe_a_l_eau
    Même sur du microcontrolleur ????
    Oui.

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    • Un paramètre ne peut faire moins d'un int de large. Inutile de définir des paramètres de type char ou short... Le code de conversion ne fait qu'alourdir et ralentir le programme...
    hmm... terrain glissant :
    c'est en effet une optimisation assez répandue, mais loin d'être vraie pour tous les compilateurs et toutes les plate-formes.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Décembre 2005
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 8
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    [*]<malloc.h> n'est pas standard. C'est <stdlib.h>[*]main() retourne int. Toujours.
    voila c'est corrigé, thanks

    Citation Envoyé par Emmanuel Delahaye
    [*]Un paramètre ne peut faire moins d'un int de large. Inutile de définir des paramètres de type char ou short... Le code de conversion ne fait qu'alourdir et ralentir le programme...[*]Dans traiter(), il y a un ; après le while(). C'est normal (il est préférable de mettre les {], c'est plus clair, même si elles sont vides.)
    j'en tiendrai compte dans mes prochains programmes, thanks.

    Citation Envoyé par Emmanuel Delahaye
    [*]Le cast de malloc() est inutile.
    ca marche pas chez moi sans le cast
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Error:  jeu.cpp(56,9):Cannot convert 'void *' to 'unsigned char *'
    (compilateur: Borland C++ 5.02)

    Citation Envoyé par Emmanuel Delahaye
    [*]malloc() peut echouer
    tous les appels de malloc on été controlé, sauf le tout premier qui n'est appelé qu'une seul fois et qui reserve 1 octet, l'erreur ne vient pas de lui puisque ca marche jusqu'au rang 7.

    bilan, ben ca marche tjs pas :/ j'ai exactement le même problème

  10. #10
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par kasaweb
    ca marche pas chez moi sans le cast
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Error:  jeu.cpp(56,9):Cannot convert 'void *' to 'unsigned char *'
    (compilateur: Borland C++ 5.02)
    L'extension de fichier C est .c et pas .cpp...

  11. #11
    Nouveau membre du Club
    Inscrit en
    Décembre 2005
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 8
    Par défaut
    Citation Envoyé par Skyrunner
    L'extension de fichier C est .c et pas .cpp...
    ca n'a aucun impact sur mon compilateur, .c ou .cpp c'est pareil pour lui

    en tout cas, j'ai renommé en .c et ca change rien :/

    thanks anyway

  12. #12
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par kasaweb
    ca n'a aucun impact sur mon compilateur, .c ou .cpp c'est pareil pour lui

    en tout cas, j'ai renommé en .c et ca change rien :/

    merci en tout cas
    Ah, je connais pas Borland, mais je sais que si on compile un code C avec g++, ce dernier signale une erreur pour le cast de malloc.

  13. #13
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par kasaweb
    ca n'a aucun impact sur mon compilateur, .c ou .cpp c'est pareil pour lui

    en tout cas, j'ai renommé en .c et ca change rien :/
    Alors il faut vérifier la configuration du projet, et demander C au lieu de C++.

  14. #14
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Ton code m'a l'air compliqué, mais bon c'est peut être moi qui a du mal a comprendre....

    Ici tu alloues un tableau de 2 pointeurs de type "mtypeS" :
    Et ici tu initialises le premier pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t[0]=(mtypeS *)malloc(sizeof(mtypeS));
    Mais qu'en est-il du deuxième pointeur ?
    Puisque ensuite tu les passes en paramètres à la fonction "traiter" en utilisant une boucle alors que t[1] n'est pas initialisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (i=1; i<n; i++)
       {
        traiter(t[(i+1)%2],t+i%2);
        [....]
       }

  15. #15
    Nouveau membre du Club
    Inscrit en
    Décembre 2005
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 8
    Par défaut
    Citation Envoyé par crocodilex
    Ici tu alloues un tableau de 2 pointeurs de type "mtypeS" :
    Et ici tu initialises le premier pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t[0]=(mtypeS *)malloc(sizeof(mtypeS));
    Mais qu'en est-il du deuxième pointeur ?
    Puisque ensuite tu les passes en paramètres à la fonction "traiter" en utilisant une boucle alors que t[1] n'est pas initialisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (i=1; i<n; i++)
       {
        traiter(t[(i+1)%2],t+i%2);
        [....]
       }
    traiter() recoit une chaine source et l'adresse d'un pointeur. Elle lit la chaine source, alloue dynamiquement l'espace pour le resultat et transmet son adresse au pointeur donné en argument: traiter (mtypeS *src, mtypeS **dest)

    à la premiere exécution de la boucle, ca donne ceci
    i = 1 => t[(i+1)%2]<=>t[0] et t+i%2 <=> t+1

    t[0] est connu, t[1] sera le resultat de la fonction

    je sais pas si j'étais assez clair :/

Discussions similaires

  1. Erreur incompréhensible
    Par Progs dans le forum C++
    Réponses: 13
    Dernier message: 21/06/2005, 14h59
  2. [2.1][jdk1.3][Junit] Erreur incompréhensible!
    Par Sniper37 dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 29/04/2005, 19h03
  3. Erreur incompréhensible à la ligne 200 (sur 190 ?!)
    Par transistor49 dans le forum Qt
    Réponses: 3
    Dernier message: 22/03/2005, 23h09
  4. [Fichiers] Erreur incompréhensible
    Par Clorish dans le forum Langage
    Réponses: 5
    Dernier message: 14/12/2004, 17h18
  5. [JSP] Erreur incompréhensible
    Par xxaragornxx dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 09/09/2003, 16h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo