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 de segmentation (os court :'( )


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 6
    Par défaut Erreur de segmentation (os court :'( )
    Bonjour à tous,
    J'ai un gros problème d'erreur de segmentation dans mon programme. Pourriez vous m'aider à le trouver et merci beaucoup d'avance à tous ceux qui vont s'intéresser à mon problème. A plus

    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
     
    //Structure des produits de la société (fichier.h)
    typedef struct l1{
    	char nomp[30];
    	struct l1 *suivant;
    } Elt1;
     
    typedef Elt1 *ListeP;
     
     
    //Structure de données Société
    typedef struct {
    //	int clesociete;
    	char nom[30];
    	char adresse[50];
    	ListeP Produits;
    } Societe;
     
     
     
     
     
    (le fichier .c)
    ListeP ajoutP (ListeP prod, char *nm)
    {ListeP new=prod;
    prod=(ListeP)malloc(sizeof(Elt1));
    strcpy(prod->nomp, nm);
    prod->suivant = new;
    return prod;
    }
     
    Societe ajoutSociete ()
    {
    Societe s;
    s.Produits=NULL;
    printf("Saisissez le nom de la société : ");
    scanf("%s",s.nom);
    printf("Saisissez l'adresse de la socitété : ");
    scanf("%s",s.adresse);
    printf("Saisissez le nom du produit : ");
    printf("bouh1");
    s.Produits = ajoutP(s.Produits, "tondeuse");
    printf("bouh2");
    printf("%s %s",s.nom,s.adresse);
    }
     
    main()
    {
    Societe tmp;
    tmp=ajoutSociete();
    printf("%s %s %s",tmp.nom,tmp.adresse,tmp.Produits->nomp);
    }

  2. #2
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    Bonjour :
    Si tu le faisais après le malloc ???
    Et je ne suis pas sûr que tu puisse copier des structures directement.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  3. #3
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 6
    Par défaut
    Je suis vraiment désolé, mais j'avais complètement oublié qu'une fonction devait contenir un return (ajoutSociete dans mon cas) ...
    Vraiment désolé ...
    Merci encore

  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 grizzlyx
    J'ai un gros problème d'erreur de segmentation dans mon programme.
    Merci de livrer la version qui compile...
    Project : Forums
    Compiler : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums2\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `ajoutP':
    main.c:25: warning: implicit declaration of function `malloc'
    main.c:26: warning: implicit declaration of function `strcpy'
    main.c: At top level:
    main.c:32: warning: function declaration isn't a prototype
    main.c: In function `ajoutSociete':
    main.c:34: error: `NULL' undeclared (first use in this function)
    main.c:34: error: (Each undeclared identifier is reported only once
    main.c:34: error: for each function it appears in.)
    main.c:35: warning: implicit declaration of function `printf'
    main.c:36: warning: implicit declaration of function `scanf'
    main.c:41: warning: passing arg 2 of `ajoutP' discards qualifiers from pointer target type
    main.c: At top level:
    main.c:47: warning: return type defaults to `int'
    main.c:47: warning: function declaration isn't a prototype
    Process terminated with status 1 (0 minutes, 2 seconds)
    3 errors, 8 warnings
    Ceci compile et s'exécute, mais n'est ni fiable ni optimisé.
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    //Structure des produits de la société (fichier.h)
    typedef struct l1
    {
       char nomp[30];
       struct l1 *suivant;
    }
    Elt1;
     
    typedef Elt1 *ListeP;
     
    //Structure de données Société
    typedef struct
    {
    // int clesociete;
       char nom[30];
       char adresse[50];
       ListeP Produits;
    }
    Societe;
     
    ListeP ajoutP (ListeP prod, char const *nm)
    {
       ListeP new = prod;
       prod = (ListeP) malloc (sizeof (Elt1));
       strcpy (prod->nomp, nm);
       prod->suivant = new;
       return prod;
    }
     
    Societe ajoutSociete (void)
    {
       Societe s;
       s.Produits = NULL;
       printf ("Saisissez le nom de la société : ");
       scanf ("%s", s.nom);
       printf ("Saisissez l'adresse de la socitété : ");
       scanf ("%s", s.adresse);
       printf ("Saisissez le nom du produit : ");
       printf ("bouh1");
     
       s.Produits = ajoutP (s.Produits, "tondeuse");
     
       printf ("bouh2");
       printf ("%s %s", s.nom, s.adresse);
     
    /* -ed- BUG : manquait */
       return s;
    }
     
    int main (void)
    {
       Societe tmp;
       tmp = ajoutSociete ();
       printf ("%s %s %s", tmp.nom, tmp.adresse, tmp.Produits->nomp);
     
       return 0;
    }

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Et n'utilise pas scanf("%s"), c'est aussi dangereux qu'utiliser gets().
    Sachant que seuls les gourous savent utiliser scanf() correctement (et que je n'en fais pas partie), je te conseille d'utiliser fgets() à la place.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    A titre personnel, il y a deux choses qui me chagrinent quelque peux:

    La premiere, c'est que, comme la liste est créée dynamiquement, il me semblerait utile d'utiliser plutot un pointeur comme parametre et comme type de retour de la fonction ajouteP (avec l'adaptation qui en découle), qui deviendrait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ListeP* ajoutP (ListeP* prod, char *nm)
    {
        ListeP *new=prod;
        prod=malloc(sizeof(Elt1));
        strcpy(prod->nomp, nm);
        prod->suivant = new;
        return prod;
    }
    ne serait-ce que parce que faire un malloc sur autre chose qu'un pointeur (ou un pointeur de pointeur)

    La deuxieme, c'est au niveau de la logique en elle-meme de cette fonction:

    Tout laisse à croire que, effectivement, tu décide de travailler avec une liste simplement chainée...

    Il semblerait donc logique que l'ajout se fasse... en fin de liste...

    Or la logique suivie rajoute un élément... en début de liste...

    Bref, la logique réelle et celle des noms sont en contradiction...

    De deux choses l'une:

    • Soit, tu veux utiliser un système de type FILO (First In, Last Out),
    • Soit tu veux utiliser effectivement une file (avec tout ce que cela implique: possiblité de tri, d'insertion au début, au milieu ou à la fin...)


    Dans le premier cas, le nom du type serait plus logiquement pile (ou similaire) et le pointeur sur l'élément actuellement nommé suivant serait plus judicieusement nommé precedent, la fonction ajouteP pouvant alors rester sensiblement pareille (à l'exception du fait qu'il faudrait modifier suivant en precedent )

    Dans le second cas, la fonction ajouteP devrait soit etre renommée judicieuxement en "inseredebutP" (par exemple), car c'est ce qu'elle fait, soit etre modifiée pour ajouter effectivement le nouvel élément... en fin de liste...

    Ce qui signifie: avoir réellement, avant l'ajout, l'acces au dernier élément de la liste, et utiliser, selon le début du code new->suivant = prod, et non prod->suivant= new...

    D'ailleurs, quand on y pense... et sans prendre en compte les éléments de réflexion que je viens de livrer...

    Pourquoi ne pas, tout simplement, allouer directement le nouvel élément sur new sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ListeP* ajoutP (ListeP* prod, char *nm)
    {
        ListeP *new;
        new=malloc(sizeof(Elt1));
        strcpy(prod->nomp, nm);
        prod->suivant = new;
        return new;
    }


    <EDIT>: cette simple modification aurait le dont "quasi miraculeux" de faire correspondre la logique utilisée avec la logique du nommage des différents éléments de structures (ajouter le nouvel élément apres le dernier, et non ajouter la liste existante "a la suite" du nouvel élément)</EDIT>

    PS: je sais que ce ne sont là que quelques détails d'implémentation, mais, l'expérience m'a déjà prouvé à maintes reprises qu'il est beaucoup plus facile de travailler avec des variables dont le nom correspond réellement à ce que l'on veut faire
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 16
    Dernier message: 14/05/2007, 14h59
  2. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 18h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 13h42
  4. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18

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