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


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Inscrit en
    Novembre 2010
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 1
    Par défaut Erreur de segmentation
    Bonjour,

    Je ne suis pas étudiant en informatique, c'est juste une option, et je débute, merci d'être indulgents.

    Pour information : j'ai fait un programme qui approxime l'intégrale d'une fonction avec la méthode de Romberg en la découpant n fois. Je fais varier n jusqu'à NMAX définie au début du code puis j'enregistre le résultat pour chaque n.

    Le problème : Dès que NMAX est assez important (12 en gros chez moi) ça plante avec une erreur de segmentation. Apparemment il faut faire une allocation dynamique. Je n'y arrive pas, il me faudrait un exemple, alors si vous pouviez m'adapter les quelques lignes utile, je vous serai très reconnaissant.

    Voici le code : l'erreur retournée est : (debug)
    Program received signal SIGSEGV, Segmentation fault.
    0x0000000000400c19 in int_romberg () at rombergstat.c:63
    63 printf("n=%d i=%d j=%d T[%d][%d]=%.16lf \n",n,i,j,i,j,T[i][j]);
    Enfin, voici le 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
    85
    86
    87
    88
    89
    90
    91
    92
    93
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
     
    #define PI 3.1415926535
     
    FILE *fichier;
     
    ///////////////
    /* A DEFINIR */
    ///////////////
    double func(double x){
    return( exp(-x)*sin(1/(x*x)) );      // CHOISIR FCT
    }
    double a=0.1;          // CHOISIR BORNE INF
    double b=10;          // CHOISIR BORNE SUP
    int NMAX=20;         // CHOISIR NB ETAPES
    ///////////////
    /* FONCTION DEFINIE */
    ///////////////
     
    /* procedure integration romberg */
    float int_romberg(){
    int n=1;
     
    // creation et ouverture fichier donnees
    fichier=fopen("int_romberg.txt","w+");
     
    double T[NMAX][NMAX];    // def matrice T
     
     // initialisation a zero
           int k=0,l=0;
           for(k=0;k<NMAX;k++){
           for(l=0;l<NMAX;l++){
           T[k][l]=0;
           }
           }
     
    for(n=1;n<NMAX+1;n++){
       double h=1.*(b-a); // def h0
     
     
     
     
       int i=0,j=0,m=0;
       T[0][0]=1.*2/h*(func(a)+func(b)); // ini T00
     
          for(i=1;i<n+1;i++){ // boucle sur i jusque n
          double S=0.;
     
             for(m=1;m<pow(2,i-1)+1;m++){
             S=S+func(a+(2*m-1)*h/2); // Calcul d'une somme
             }
     
          T[i][0]=1.*1/2*(T[i-1][0]+h*S); // def Ti0
          h=h/2; // h redefini
     
             for(j=1;j<i+1;j++){ // boucle sur j jusque i
     
             T[i][j]=1.*(pow(4,j)*T[i][j-1]-T[i-1][j-1])/(pow(4,j)-1);
     
                // Etat avancement
                printf("n=%d   i=%d   j=%d   T[%d][%d]=%.16lf \n",n,i,j,i,j,T[i][j]);
     
             } // fin boucle sur j
          } // fin boucle sur i
     
       double r=0.;
       r=T[n][n]; // integrale
     
       // ecriture dans un fichier data
       fprintf(fichier,"%d  %f\n",n,r);
     
     
    } // fin de la boucle de n nb de decoupe
     
    fclose(fichier); // fermeture fichier donnees
     
    return(0);
    }
     
     
    /* procedure principale */
    int main(){
     
    int_romberg(); // appel fonction
    printf("FIN\n");
     
    // affichage trace avec bash
    system("bash plot.bash");
     
    return(0);
    }
    Merci d'avance à ceux qui m'aideront =)

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Salut

    Je ne pourrai pas t'aider concernant le domaine algorithmique de la méthode de Romberg, que je ne connais pas.

    Par contre, regarde le déroulement de tes boucles, il y a des choses qui "coincent" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    double T[NMAX][NMAX];
    (...)
    for(n=1;n<NMAX+1;n++) /* "n" va jusqu'à XMAX inclus */
    {
    (...)
    	for(i=1;i<n+1;i++) /* "i" va donc lui aussi jusqu'à NMAX */
    	{
    		(...)
    		for(j=1;j<i+1;j++) /* du coup, même chose pour "j" */
    		{
    			T[i][j]=1.*(pow(4,j)*T[i][j-1]-T[i-1][j-1])/(pow(4,j)-1);
    			printf("n=%d   i=%d   j=%d   T[%d][%d]=%.16lf \n",n,i,j,i,j,T[i][j]);
    			(...)
    les valeurs de "i" et "j" vont, à un moment donné, provoquer un accès en dehors du tableau. Et à partir de là, le programme est donc susceptible de se comporter de manière bizarre, sachant que ton tableau est sur la pile et qu'en cas de débordement d'autres variables peuvent être affectées (modifiée) à cause du débordement.
    Attention aussi : en C, le premier élément d'un tableau commence à l'indice 0.

    Le "segmentation fault" juste au niveau du "printf" est peut-être la conséquence de la ligne précédente, qui, lorsque tu débordes du tableau, peut éventuellement écraser d'autres variables (comme par hasard "i" et/ou "j"...) et par conséquent lorsque le "printf" tente de lire l'objet T[i][j] (où "i et "j" peuvent avoir des valeurs complètement bizarres) cela provoque un crash (?). Ceci n'est qu'une hypothèse. Tu peux vérifier en n'affichant que "i" et "j" jusqu'au crash, et regarder si au dernier passage ces deux variables affichent des valeurs totalement bidons sorties du chapeau magique. ^^

    En tout cas, extrapolation ou pas de ma part, il faut solutionner ton problème de débordement de tableau, car cela reste un bug quoi qu'il arrive.

  3. #3
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    en fait ton gros bug vient de la =P
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(n=1;n<NMAX+1;n++){
    Ben oui vu que T[20][x] n'existe pas x)
    (pareil pour T[0][20] par exemple).
    Quant tu déclare un tableau de 20 ton tableau commence de T[0] a T[19];

    D'ailleurs pourquoi pas faire ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(n=0;n<NMAX;n++){
    Si c'est pour qu'il ecrit correctement dans le texte ( de 1 a 20 donc).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fprintf(fichier,"%d  %f\n",n+1,r);
    Apres ton programme a plusieurs souci , des variable globale, et NMAX doit être un define , et un gros problème d’incrémentation =/.

    Voila comment je l'aurais coder (jai rien changer , jai juste rendu ton code plus lisible ,sans variable globale).
    D’ailleurs tu peux réduire le nombre i,l,j,n par exemple suffit largement.
    Pour initialiser un double un simple S = 0; suffit , et dernière chose on met la déclaration des variable toujours au début (et encore moins dans une boucle =P).
    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
    85
     
    #define PI 3.1415926535
    #define NMAX 20
     
    ///////////////
    /* A DEFINIR */
    ///////////////
    double func(double x)
    {
        return( exp(-x)*sin(1/(x*x)) );      // CHOISIR FCT
    }
    ///////////////
    /* FONCTION DEFINIE */
    ///////////////
    float int_romberg()
    {
        int l,m,n,i,j,k;
        double h,S,r;
        FILE *fichier;
        double a=0.1;          // CHOISIR BORNE INF
        double b=10;          // CHOISIR BORNE SUP
     
        // creation et ouverture fichier donnees
        fichier=fopen("int_romberg.txt","w+");
     
        double T[NMAX][NMAX];    // def matrice T
     
        // initialisation a zero
        for(k=0;k<NMAX;k++) // tu peux remplacer k par i
            for(l=0;l<NMAX;l++)
                T[k][l]=0;
     
     
        for(n=1;n<NMAX;n++) 
        {
            h=1.*(b-a); // def h0
     
            T[0][0]=1.*2/h*(func(a)+func(b)); // ini T00
     
            for(i=1;i<n+1;i++)// boucle sur i jusque n
            {
                S=0;
     
                for(m=1;m<pow(2,i-1)+1;m++) // tu peux replacer m par l
                    S=S+func(a+(2*m-1)*h/2); // Calcul d'une somme
     
                T[i][0]=1.*1/2*(T[i-1][0]+h*S); // def Ti0
                h=h/2; // h redefini
     
                for(j=1;j<i+1;j++)// boucle sur j jusque i
                {
     
                    T[i][j]=1.*(pow(4,j)*T[i][j-1]-T[i-1][j-1])/(pow(4,j)-1);
     
                    // Etat avancement
                    printf("n=%d   i=%d   j=%d   T[%d][%d]=%.16lf \n",n,i,j,i,j,T[i][j]);
     
                } // fin boucle sur j
            } // fin boucle sur i
     
            r=T[n][n]; // integrale
     
            // ecriture dans un fichier data
            fprintf(fichier,"%d  %f\n",n,r);
     
     
        } // fin de la boucle de n nb de decoupe
     
        fclose(fichier); // fermeture fichier donnees
     
        return 0;
    }
     
     
    /* procedure principale */
    int main(){
     
        int_romberg(); // appel fonction
        printf("FIN\n");
     
        // affichage trace avec bash
        system("bash plot.bash");
     
        return 0;
    }

Discussions similaires

  1. Erreurs de segmentation !
    Par anti-conformiste dans le forum Applications et environnements graphiques
    Réponses: 16
    Dernier message: 18/10/2005, 11h11
  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