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 :

Mon programme plante


Sujet :

C

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 15
    Points : 5
    Points
    5
    Par défaut Mon programme plante
    Bonjour j'ai besoin de vous aide SVP


    1- This C function performs its job most of the time, but has several defects (bugs, error handling, etc.) in specific situations.

    Modify the code to make it as robust as possible, in order to make sure it will not crash or cause any problem in the application, even if the arguments provided to the function are incorrect.

    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
    /*
      double_whitespaces:
      Copy the "msg" buffer of size "size" into the "dest" buffer,
      while doubling any blank character found in the source buffer.
    */
     
    int double_whitespaces(char *msg, int size, char *dest) {
      int ret;
      char *ptr;
     
      char *buf;
     
      buf = malloc(size);
     
      ptr = msg;
      while (ptr < msg + size) {
        if (*ptr == '%')     // % char is forbidden
          goto error;
        if (*ptr == ' ')  {
          *buf++ = ' ';
          *buf++ = ' ';
        } else {
          *buf++ = *ptr;
     
        }
        ptr++;
      }
      free(buf);
      strcpy(dest, buf);
      return 0;
    error:
      return -1;
    }
    c'est en anglais mais la question cest de proposer une amilioration du code pour qu'il ne plante pas sachant qu'il marche mais il beug de temps en temps

    Merci d'avance

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Utilise les balises code (bouton #) et indente ton code, tu y trouvera facilement une erreur.

    Sinon, il faut mieux vérifier la taille de ta chaine de caractères.

    Pour finir, tu libre buf avant dans copier le contenu dans msg...

  3. #3
    Futur Membre du Club
    Inscrit en
    Mars 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Oula , !!!


    tu peux détailler encore plus par ce que là je ne suis pas sur de vous suivre ( juste une petite remarque je ne suis pas expert en C je fait du java mais on m'a obligé de passer par la donc voila avec un peu de détail et même ce que cette fonction fait parce que je ne me retrouve plus **


    merci bcp

  4. #4
    Invité(e)
    Invité(e)
    Par défaut
    Utilisation de la balise code : http://club.developpez.com/aidenouve...es/Balises.gif

    Ce qui nous donne :
    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
     
    int double_whitespaces(char *msg, int size, char *dest) {
        int ret;
        char *ptr;
        char *buf;
        buf = malloc(size);
        ptr = msg;
        while (ptr < msg + size) {
            if (*ptr == '%') // % char is forbidden
                goto error;
            if (*ptr == ' ') {
                *buf++ = ' ';
                *buf++ = ' ';
            } else {
                *buf++ = *ptr;
            }
            ptr++;
        }
        free(buf);
        strcpy(dest, buf);
     
        return 0;
    error:
        return -1;
    }
    Autant pour moi, aucun erreur n'est révélée par indentation.

    Sinon, les erreurs faciles à relever :
    1. buf est utilisé alors que free(buf) a été appelé
    2. la fonction est sensée doubler les espaces d'une chaine de caractère. Si on appelle la fonction avec la chaine " " (4 espaces) combien faudra-t-il de place pour stocker la réponse ?


    Il faudrait que tu nous montre avec quoi tu testes ta fonction.

  5. #5
    Futur Membre du Club
    Inscrit en
    Mars 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Merci Pour votre réponse en fait on m'a proposer la question tel que je vous ai communiquer c'est un challenge pour passer un entretien moi je suis plutot JAVA LOL mais C j'en ai fait y a 4 ans donc je me rappel presque de rien et en fait la question si vous remarquer bien c'eest noté la haut en englais c'est d'essayer de trouver pourquoi le programme plante de temp en temps c'est à dire que le programme marche bien mais mais il a des beug du a une mauvaise écriture du code et il me demande en fait de réécrir le programme de telle façon qu'il ne plante plus

  6. #6
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par yougoo Voir le message
    en fait on m'a proposer la question tel que je vous ai communiquer c'est un challenge pour passer un entretien
    Je rappelle le titre du sujet :
    Mon programme plante
    J'ai un peu l'impression de me faire entourlouper.

    il me demande en fait de réécrir le programme de telle façon qu'il ne plante plus
    De même que les forums ne sont pas là pour faire les devoirs des étudiants, nous n'allons pas passer des entretiens d'embauche à ta place.

  7. #7
    Futur Membre du Club
    Inscrit en
    Mars 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    je peux vous assurer monsieur que j'ai été fait pour coder des programmes j'ai un dan en programmation et je me renseigne et c'est tous a fait normale et quant j'ai écrit mon programme plante c'était bien le cas dans l'énoncé c dit que le programme plante, et du moment que c'est moi qui essai de voir pour quoi ça plante donc c'est le mien et une fois devant le recreteur je lui montrais que je suis bien motivé pour le poste et je ne vous rappel encore une fois que je n'ai pas touché au C ça fait déja 4 ans

    de tout façon on es des simples étudiant et c'est notre fase " apprendre " et je ne sais pas pour quoi les professionels sont aussi dur ladessus on dirait qu'il sont né des professionnell

    Merci pour vos réponse je vous tiendrais au courant quant je serais ambouché

  8. #8
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Le code est vérolé (utilisation de buf dans strcpy() APRES libération)

    L'énoncé est imprécis et ne permet pas de faire un code fiable à coup sûr.
    Il ne précise pas
    - si le buffer source représente une chaine de caractères C (terminée par '\0')
    - si le buffer destination doit représenter une chaine de caractères C
    (le fait de tester des '%' ou ' ' n'est pas une preuve absolue)
    - si le paramètre size représente la taille du buffer source ou celle du buffer de destination ou les deux.

    En considérant le code proposé, on peut penser que le buffer de destination doit représenter une chaine de caractères C (utilisation de strcpy()) et donc supposer que le buffer source également.
    Dans ce cas, le paramètre size est inutile pour donner la taille de la chaine source (on peut la connaitre si besoin) et qu'il représente alors la taille du buffer destination que sinon on n'a aucun moyen de connaitre.

    Au final, la fonction doit largement être repensée à cause :
    - de l'absence de tests sur la validité des paramètres
    - de l'inutilité de faire une allocation dynamique
    - de la suppression de ces vilains goto

    On peut partir dans cette hypothèse sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    1-  si dest == NULL sortir sans échec (la fonction n'a rien à faire)
        sinon si size est <=0 sortir en erreur (on ne peut avoir des tableaux de taille nulle)
              sinon si msg == NULL mettre '\0' dans dest et sortir sans échec
                    sinon continuer
    2- donc ici size>0, dest != NULL et msg != NULL
       - créer une variable destmax = dest+size-1
       - tant que *msg != '\0' et dest < destmax  
          - si *msg == '%' sortir en erreur
          - si *msg == ' ' *dest++ = ' ';
          - si dest<destmax  *dest++ = *msg++;
       - *dest = '\0'
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  9. #9
    Futur Membre du Club
    Inscrit en
    Mars 2011
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 15
    Points : 5
    Points
    5
    Par défaut quelqu'un pourrais m'aider SVP
    Bonjour a tous

    est ce qu'il y a quelqu'un qui peux me dire sur quel partie du programmation C je devrais chercher pour que je puisse comprendre le programme suivant : en fait je voudrais comprendre le fonctionnellement du programme mais en lisant un tutorial sur cette partie .

    et merci d'avance

    voila le programme


    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
    int double_whitespaces(char *msg, int size, char *dest) {
      int ret;
      char *ptr;
     
      char *buf;
     
      buf = malloc(size);
     
      ptr = msg;
      while (ptr < msg + size) {
        if (*ptr == '%')     // % char is forbidden
          goto error;
        if (*ptr == ' ')  {
          *buf++ = ' ';
          *buf++ = ' ';
        } else {
          *buf++ = *ptr;
     
        }
        ptr++;
      }
      free(buf);
      strcpy(dest, buf);
      return 0;
    error:
      return -1;
    }

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    SI vous voulez que des tutos, il fallait juste cliquer sur les cours de Developpez.com ->
    http://c.developpez.com/cours/?page=lang-c#initiation-c

    Notamment sur les chaines de caractères, les tableaux et les pointeurs.
    http://melem.developpez.com/tutoriel...ion-langage-c/
    http://chgi.developpez.com/pointeur/
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  11. #11
    Membre expérimenté Avatar de Ngork
    Homme Profil pro
    Barbare IT
    Inscrit en
    Avril 2009
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Barbare IT
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 160
    Points : 1 372
    Points
    1 372
    Par défaut fuite de mémoire
    L'utilisation d'un vilain goto pour sortir directement de la boucle pourrait éventuellement être la cause d'un débordement de la pile (cela dépend du code effectivement généré) après un grand nombre d'appels sortant en erreur, mais j'en doute ...

    Mais l'allocation dynamique de mémoire, non libérée, conduit inévitablement à une fuite de mémoire, potentiellement fatale après plusieurs appels en raison de l'absence de contrôle de la réussite de l'allocation.

    Et surtout, tu devrais allouer au moins le double de size, si size est bien le nombre d'octets de ta chaîne d'entrée, au cas où tous les caractères seraient des espaces, or tu n'alloues que size octets, que tu veux libérer (sans réussir puisque buf a une autre valeur que celle avec laquelle tu l'as initialisé) avant même d'en copier le contenu ... le plus étonnant n'est donc pas que ton programme plante parfois, mais qu'il ne plante pas à chaque fois puisqu'il écrit systématiquement hors de la mémoire allouée dès qu'il a rencontré au moins un espace !

    Par ailleurs :

    - rien n'indique avec certitude que ta chaine se termine par un \0 puisque tu fournis la valeur size,
    - tu ne veux visiblement rien récupérer dans dest si la sortie est en erreur,
    - tu n'initialises ni n'utilises la valeur de ret.

    J'ajoute que la fonction doit logiquement retourner le nombre d'octets effectivement écrits (sans le caractère nul final) plutôt que zéro.

    Voici un exemple de code, corrigé de mes remarques :

    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
     
    /*
      double_whitespaces:
      Copy the "msg" buffer of size "size" into the "dest" buffer,
      while doubling any blank character found in the source buffer.
      Returns number of wrote bytes (whithout the ending null char)
      or -1 if an error appears.
    */
     
    int double_whitespaces(char *msg, int size, char *dest)
    {
      int ret = -1;
      char *ptr , *ptr_buf;
      char *buf;
     
      buf = calloc(2 , size+1);
     
      if (buf) // memory allocation is OK
        {
          ret = 0;
          ptr = msg;
          ptr_buf = buf;
     
          while (ptr < msg + size)
            {
              if (*ptr == '%')     // % char is forbidden
                {
                  ret = -1;
                  break;
                }
     
              if (*ptr == ' ')
                {
                  *ptr_buf++ = ' ';
                  *ptr_buf++ = ' ';
                }
              else
                {
                  *ptr_buf++ = *ptr;
                }
     
              ptr++;
            }
     
          if (ret == 0)
            {
              ret = (int) (ptr_buf - buf);
              memcpy(dest, buf, ret + 1);
            }
     
          free(buf);
        }
     
      return ret;
    }
    Franchement, je n'avais jamais vu un code aussi pourri !
    Il fonctionnait parfois ???

    Bien codement,
    N'gork.

Discussions similaires

  1. Ma souris logitech m'a planté mon programme!
    Par lima64 dans le forum Visual C++
    Réponses: 0
    Dernier message: 08/02/2009, 01h50
  2. Problème avec strcpy : mon programme plante
    Par Titi41 dans le forum Débuter
    Réponses: 4
    Dernier message: 06/11/2008, 12h02
  3. fonction qui plante mon programme
    Par étoile de mer dans le forum Débuter
    Réponses: 21
    Dernier message: 22/08/2008, 15h08
  4. Mon programme qui s'exécutait bien, plante
    Par Yokai dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 22/05/2008, 18h16
  5. Réponses: 11
    Dernier message: 17/03/2003, 10h56

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