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 :

Programme très court : erreur de segmentation


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Avril 2005
    Messages
    156
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 156
    Points : 76
    Points
    76
    Par défaut Programme très court : erreur de segmentation
    Bonsoir,

    J'ai une erreur de segmentation dans le programme suivant :

    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <limits.h>
    #include <signal.h>
    #include <sys/wait.h>
     
    typedef struct scapteur {
      pid_t num;
      unsigned int total;
      unsigned char termine;
    } *Capteur;
     
    Capteur nouv_capteur(void){
      Capteur c = (Capteur)malloc(sizeof(struct scapteur));
      c->num = getpid();
      c->total = 0;
      c->termine = 0;
      return c;
    }
     
    int main(int argc, char **argv){
      Capteur *capteurs;
      Capteur c;
      *capteurs = nouv_capteur();
      return EXIT_SUCCESS;
    }
    Je bloque dessus depuis pas mal de temps, sans savoir d'où vient l'erreur (peut-être suis-je fatigué !)...quelqu'un peut me dire où est l'erreur ?

    Merci !

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    je crois que tu inverses partout pointeur sur la structure et structure..

    Moi je ferais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct scapteur {
      pid_t num;
      unsigned int total;
      unsigned char termine;
    } Capteur;
    Puis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Capteur *nouv_capteur(void){
      Capteur *c = (Capteur *)malloc(sizeof(struct Capteur));
      if ( c != NULL )
       {
         c->num = getpid();
         c->total = 0;
         c->termine = 0;
       }
      return c;
    }

    Et enfin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main(int argc, char **argv){
      Capteur *capteurs=NULL;
     
      capteurs = nouv_capteur();
      return EXIT_SUCCESS;
    }

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    Je dirais meme plus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void nouv_capteur(Capteur *c){
      if(c == NULL)
      {
         c = malloc(sizeof(struct Capteur));
      }
      if ( c != NULL )
       {
         c->num = getpid();
         c->total = 0;
         c->termine = 0;
       }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(int argc, char **argv){
      Capteur *capteurs=NULL;
     
      nouv_capteur(capteurs);
      if(capteurs != NULL)
      {
         [...]
         free(capteurs), capteurs = NULL;
      }
      return EXIT_SUCCESS;
    }

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Points : 361
    Points
    361
    Par défaut
    pour souviron34 ton dernier bloc contient une erreure, nouv_capteur renvoi un pointeur, donc il faut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    capteurs = nouv_capteur();
    (pas de * devant capteur).

    Ensuite Skyrunner ton code ne marchera pas !!! tu passes un pointeur que tu veux modifier à l'intérieur d'un e fonction, résultat tu alloues effectivement un capteur mais en sortie de fonction ton pointeur est inchangé. Pour cela il faut passer l'adresse du pointeur.

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par Skyrunner
    Je dirais meme plus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void nouv_capteur(Capteur *c){
      if(c == NULL)
      {
         c = malloc(sizeof(struct Capteur));
      }
      if ( c != NULL )
       {
         c->num = getpid();
         c->total = 0;
         c->termine = 0;
       }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(int argc, char **argv){
      Capteur *capteurs=NULL;
     
      nouv_capteur(capteurs);
      if(capteurs != NULL)
      {
         [...]
         free(capteurs), capteurs = NULL;
      }
      return EXIT_SUCCESS;
    }
    Ca ne marche pas ça. le test capteurs != NULL ne passera jamais.


    Je préconise toujours de laisser à l'utilisateur le choix d'utiliser malloc ou non avec Capteur, en utilisant sous la forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Capteur c;
     
    capteurInit(&c);
     
    capteurDelete(&c); //ce qui en fait ne fera rien puisque ça n'alloue pas de mémoire dans la structure
    L'utilisateur pourra également utiliser malloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Capteur * c = malloc(sizeof(capteur));
    if(c==NULL)
    {
     fprintf(stderr, "Bad allocation");
     exit(EXIT_FAILURE);
    }
     
    capteurInit(c);
     
    capteurDelete(c);
     
    free(c);

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    Oupsss désolé erreur de ma part.

    Exact il faut passer un pointeur de pointeur.

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    Citation Envoyé par millie
    Ca ne marche pas ça. le test capteurs != NULL ne passera jamais.
    Là par contre je suis pas d'accord.

    Je repost un code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void nouv_capteur(Capteur **c){
      if(*c == NULL)
      {
         *c = malloc(sizeof(struct Capteur));
      }
      if ( *c != NULL )
       {
         *c->num = getpid();
         *c->total = 0;
         *c->termine = 0;
       }
    }

  8. #8
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par Skyrunner
    Là par contre je suis pas d'accord.
    Je parlais du premier code que tu as envoyé. Pas du deuxième que tu as posté après moi

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Points : 361
    Points
    361
    Par défaut
    perso pour se dispenser de réfléchir à ces histoires de pointeur de pointeur je préconise un renvoi de pointeur comme décrit par souviron34
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Capteur *c=new_capteur();
    plus simple et plus sur...

  10. #10
    Membre éclairé 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
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par Skyrunner
    Là par contre je suis pas d'accord.

    Je repost un code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void nouv_capteur(Capteur **c){
      if(*c == NULL)
      {
         *c = malloc(sizeof(struct Capteur));
      }
      if ( *c != NULL )
       {
         *c->num = getpid();
         *c->total = 0;
         *c->termine = 0;
       }
    }
    Je suis d'avis avec millie. Etant donné que beaucoup de programmeur n'initialisent pas leur pointeurs à NULL lors de leur déclaration, ton code risque de crasher.
    J'aurais donc fais comme ça :
    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
    void nouv_capteur(Capteur **c)
    {
        *c = malloc(sizeof(struct Capteur));
     
        if ( *c != NULL )
        {
            *c->num = getpid();
            *c->total = 0;
            *c->termine = 0;
        }
        else
        {
            /* Traitement erreur malloc */
        }
    }
    Mais sinon, je préfère la méthode classique qui est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Capteur *nouv_capteur(void)
    {
        Capteur *c = malloc(sizeof *c);
     
        if ( c != NULL )
        {
            c->num = getpid();
            c->total = 0;
            c->termine = 0;
        }
     
        return c;
    }

  11. #11
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 40
    Points : 46
    Points
    46
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main(int argc, char **argv){
      Capteur *capteurs;
      Capteur c;
      *capteurs = nouv_capteur();
      return EXIT_SUCCESS;
    }
    Pour répondre directement à ta question ton erreur de segmentation viens de ce morceau de code.

    Capteur *capteurs; n'est pas initialisé.

    *capteurs = nouv_capteur(); Tu tentes d'accéder à qq chose pointé alors que tu n'as rien initialisé.

    Sinon niveau conception voir plus haut ce sera peut être plus approprié. Ajoute un malloc et ça devrait marcher.

    Capteur *capteurs = malloc (n*sizeof(Capteur));

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    @crocodilex

    Il est vrai que si le pointeur n'est pas initialisé à NULL bah ça marche pas .

    Bon ok l'autre méthode est mieux

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par reptils
    pour souviron34 ton dernier bloc contient une erreure, nouv_capteur renvoi un pointeur, donc il faut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    capteurs = nouv_capteur();
    (pas de * devant capteur).

    Exact désolé vu l'heure je devais commencer à m'endormir...

    J'ai corrigé dans le post..

  14. #14
    Expert éminent sénior
    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
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par reptils
    perso pour se dispenser de réfléchir à ces histoires de pointeur de pointeur je préconise un renvoi de pointeur comme décrit par souviron34
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Capteur *c=new_capteur();
    plus simple et plus sur...
    +1

    Je ne comprends pas qu'on veuille faire autrement...

  15. #15
    Expert éminent sénior
    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
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par crocodilex
    Mais sinon, je préfère la méthode classique qui est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Capteur *nouv_capteur(void)
    {
        Capteur *c = malloc(sizeof *c);
     
        if ( c != NULL )
        {
            c->num = getpid();
            c->total = 0;
            c->termine = 0;
        }
     
        return c;
    }
    Ah, enfin du vrai C simple et clair !

  16. #16
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par Emmanuel Delahaye

    Je ne comprends pas qu'on veuille faire autrement...
    Je ne sais pas si tu avais lu mon message précédent pù je dirais qu'on pouvait laisser le choix à l'utilisateur de faire un malloc ou non sur une variable de type Capteur en prénant une syntaxe comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Capteur c;
     
    capteurInit(&c);
     
    capteurDelete(&c); //ce qui en fait ne fera rien puisque ça n'alloue pas de mémoire dans la structure
    L'utilisateur pourra également utiliser malloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Capteur * c = malloc(sizeof(capteur));
    if(c==NULL)
    {
     fprintf(stderr, "Bad allocation");
     exit(EXIT_FAILURE);
    }
     
    capteurInit(c);
     
    capteurDelete(c);
     
    free(c);
    C'est en général ce que je fais. Ca permet d'utiliser malloc que si on le souhaite (évidemment, dans d'autres structures, capteurInit pourra faire des malloc, mais ça sera caché.

  17. #17
    Expert éminent sénior
    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
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par millie
    C'est en général ce que je fais. Ca permet d'utiliser malloc que si on le souhaite (évidemment, dans d'autres structures, capteurInit pourra faire des malloc, mais ça sera caché.
    Dans ce cas, j'ai 2 syntaxes séparées :

    statique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xxx_init (struct xxx *this);
    dynamique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    struct xxx *xxx_create (void);
    xxx_delete (struct xxx *this);
    Et ca s'utilise comme ça :

    statique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       struct xxx x;
       xxx_init (&x);
    dynamique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
       struct xxx *px = xxx_create ();
       if (px != NULL)
       {
          /* ... */
     
          xxx_delate (px), px = NULL;
       }
     
       assert (px == NULL);

Discussions similaires

  1. Réponses: 8
    Dernier message: 21/05/2010, 17h17
  2. Réponses: 1
    Dernier message: 14/05/2010, 09h00
  3. Réponses: 1
    Dernier message: 21/10/2009, 11h36
  4. Réponses: 4
    Dernier message: 27/04/2009, 20h33
  5. Erreur de segmentation (os court :'( )
    Par grizzlyx dans le forum C
    Réponses: 5
    Dernier message: 17/11/2006, 13h55

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