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 :

Segmentation fault dans mon premier code


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2017
    Messages : 2
    Par défaut Segmentation fault dans mon premier code
    Bonjour,
    je débute en C et j'ai essayé d'afficher le triangle de Pascal.
    Je ne comprends pas pourquoi j'ai cette erreur de segmentation à la ligne 59 (dans le printf d'après le debugger); j'ai essayé en changeant ma fonction triangle en void ou en enlevant le return, sans réussite. Je ne sais pas si j'appelle mal ma fonction ou si j'initialise mal mes tableaux. A moins que je fasse le free trop tôt ?
    Ca doit être une erreur banale de débutant, mais je sèche.
    Merci d'avance de vos réponses.

    Le code:

    Code C : 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
    #include <stdio.h>
    #include <stdlib.h>
     
    int triangle (int n, int **c);
    int factorielle (int nbr);
     
    int factorielle (int nbr)
    {
        int i;
        int resultat = 1;
     
        for (i=2 ; i<=nbr ; i++)
            resultat *= i;
     
        return resultat;
    }
     
    int triangle (int n, int **c)
    {
        int i,j;
     
        c = malloc( n * sizeof(int *));
            for (i=0; i<n; i++)
    {
        c[i]= malloc( n * sizeof(int *));
    }
     
        for (i=0; i<n;i++)
            for (j=0; j<n;j++)
            c[i][j]=0;
     
        for (i=0; i<n;i++)
            for (j=0; j<=i;j++)
            {c[i][j]=factorielle(i) * factorielle(j) / factorielle(i-j);
            //return c[i][j];
            }
         for (i=0; i<n; i++)
             free(c[i]);
     
    }
     
     
     
    int main()
    {
        int i,j,n;
        int **c;
        i=0;
        j=0;
        n=0;
        c=0;
     
        printf("Entrez n\n");
        scanf("%d",&n);
        triangle(n,c);
        for (i=0; i<n; i++)
        {   printf("\n");
            for (j=0; j<=i; j++)
            { printf("%d",c[i][j]);
                     }
        }
        return 0;
    }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 473
    Par défaut
    Bonjour et bienvenue,

    Il y a plusieurs erreurs et anomalies dans ton programme, dont celle-ci :

    Citation Envoyé par sebbob Voir le message
    Le code:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int main()
    {
        int i,j,n;
        int **c;
        i=0;
        j=0;
        n=0;
        c=0;
    
        printf("Entrez n\n");
        scanf("%d",&n);
        triangle(n,c);
    Tu as donné le même nom à deux variables différentes. Pour cette seule raison, le compilateur devrait au moins émettre un warning, dont il faut tenir compte (et à terme, il faudra s'arranger pour qu'il n'y en ait plus un seul, même avec des options de compilation stricte, mais tu as encore le temps de voir venir…).

    Dans le cas présent, tu passes donc la valeur du caractère « c », défini à zéro, à ta fonction triangle(). Mais telle que tu l'utilises, ce n'est pas à ce stade que le plantage se produit.

    Je vois que dans ta fonction triangle(), tu utilises des mallocs() en cascade pour réserver de la place pour ton tableau. Tu n'es pas obligé de passer tout de suite par cette fonction pour réserver de la place. Tu peux directement déclarer un tableau multidimensionnel avec int c[nb_max_de_lignes][nb_max_de_colonnes];, voire avec n en s'appuyant sur les VLAs.

    Par contre, chose importante (avec le fait que deux variables portent le même nom) : les paramètres, en C, sont passés par valeur. Donc, modifier la valeur de l'« int ** c » déclaré à la ligne 18 ne va pas automatiquement renseigner celui de la ligne 47. Ce dernier garde donc son état initial (indéfini) et, bien sûr, débouche sur un comportement indéterminé lorsqu'il est enfin utilisé par ton printf().

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sebbob Voir le message
    j'ai essayé en changeant ma fonction triangle en void ou en enlevant le return, sans réussite.
    Bonjour

    Quand on débuggue un code, on ne tente pas des trucs au petit bonheur mais on analyse plutôt chaque portion du code et on vérifie que sa conception réelle correspond à la conception qu'on en a dans sa tête...

    Citation Envoyé par sebbob Voir le message
    Je ne sais pas si j'appelle mal ma fonction ou si j'initialise mal mes tableaux.

    Le code:

    Code C : 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
    int triangle (int n, int **c)
    {
        int i,j;
     
        c = malloc( n * sizeof(int *));
            for (i=0; i<n; i++)
    {
        c[i]= malloc( n * sizeof(int *));
    }
     
        for (i=0; i<n;i++)
            for (j=0; j<n;j++)
            c[i][j]=0;
     
        for (i=0; i<n;i++)
            for (j=0; j<=i;j++)
            {c[i][j]=factorielle(i) * factorielle(j) / factorielle(i-j);
            //return c[i][j];
            }
         for (i=0; i<n; i++)
             free(c[i]);
     
    }
    Regarde attentivement ton second malloc. Demande toi "qu'est-ce que je veux allouer ?" et "est-ce que mon instruction correspond? ".

    Accessoirement tu devrais vérifier la formule de la valeur calculée à la position (n, p) car ce n'est absolument pas "n! * p! / (n - p)!"...

    Citation Envoyé par sebbob Voir le message
    A moins que je fasse le free trop tôt ?
    Là effectivement je ne comprends pas trop. Tu alloues, tu remplis puis tu libères (en oubliant le pointeur originel). Et donc à quel moment tu utilises ce qui a été rempli ??? Et ta fonction "triangle" est sensée renvoyer un int. A quoi correspond, dans ton esprit, cet entier renvoyé ??? Parce que si c'est la valeur d'un nombre calculé à la position (n, p) alors tu n'as pas besoin de calculer tout le triangle. Mais si c'est le triangle tout entier que tu veux renvoyer, alors "tout le triangle" ce n'est certainement pas un simple "int"...

    Citation Envoyé par sebbob Voir le message
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int triangle (int n, int **c)
    {
        c = ...
    }
     
    int main()
    {
        int **c;
        ...
        triangle(n,c);
        ...
    }
    Ce type d'instruction ne peut absolument pas fonctionner car tu modifies ici une variable locale "c". Et donc tout ce qui est écrit dans "c" est perdu quand la fonction se termine.

    Je sens bien ce que tu cherches à faire: faire en sorte que la fonction remplisse la variable en utilisant son adresse, de la même façon que dans cet exemple

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void remplir(int *n, int val)
    {
        (*n)=val;
    }
     
    int main()
    {
        int x=0;
        remplir(&x, 10);
        printf("x=%d\n", x);
    }

    Mais justement, comme pour mon exemple, l'analogie avec ton code doit se faire de façon complète. Ainsi dans mon exemple, je veux faire remplir un int donc je passe l'adresse de cet int à ma fonction qui va stocker cette adresse dans un int *.
    De ton côté tu veux faire remplir un int** donc tu dois passer l'adresse de cet int** à ta fonction qui devra stocker cette adresse dans un int** *.
    Bref pour résumer, si tu dois faire modifier un truc dans une fonction, tu dois alors passer l'adresse de ce truc à la fonction qui devra alors stocker et manipuler cette adresse dans un truc * (à toi de remplacer le terme "truc" par les vrais types de ton main et ne pas oublier les étoiles dans le remplacement si ces types en ont au préalable).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2017
    Messages : 2
    Par défaut MERCI !
    Merci beaucoup de vos réponses.
    J'ai besoin de quelques jours pour y réfléchir !
    A bientôt

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

Discussions similaires

  1. Réponses: 18
    Dernier message: 23/12/2009, 18h10
  2. mon premier code javascript
    Par thered dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 07/03/2009, 15h38
  3. mon premier code ne fonctionne pas.
    Par argon dans le forum Langage
    Réponses: 1
    Dernier message: 22/06/2007, 21h06
  4. [Système] exécution de mon premier code en php
    Par sasaas dans le forum Langage
    Réponses: 11
    Dernier message: 10/05/2007, 10h10
  5. [Mon premier code SQL] Multiples INNER JOIN's
    Par Paulinho dans le forum Langage SQL
    Réponses: 1
    Dernier message: 14/11/2005, 09h04

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