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
    Membre confirmé

    Inscrit en
    Octobre 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 69
    Par défaut Erreur de segmentation
    Bonjour,
    J'essaie de résoudre le problème 14 du site project euler qui demande de trouver le plus grand nombre inférieur à 1000000 qui produit la plus longue suite de Syracuse.
    Voici mon 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
    #include <stdio.h>
    #include <stdlib.h>
     
    #define N 1000000
     
    int tab[N];
     
    int syracuse(int);
    int calculNbreTermes(int);
     
    int main(int argc, char * argv[])
    {
        int i = 0, max = 0;
        int nbreTermes = 0, maxNbreTermes = 0;
     
        for(i = 0; i < N; ++i)
            tab[i] = 0;
     
        for(i = 1; i < 1000000; ++i)
        {
            nbreTermes = calculNbreTermes(i);
            if(nbreTermes >= maxNbreTermes)
            {
                max = i;
                maxNbreTermes = nbreTermes;
            }
        }
     
        printf("Max = %d\n", max);
        printf("Nbre de termes = %d\n", maxNbreTermes);
     
        return 0;
    }
     
    int syracuse(int n)
    {
        if(n % 2 == 0)
            return n / 2;
        else 
            return 3 * n + 1;
    }
     
    int calculNbreTermes(int n)
    {
        int nbreTermes = 0;
        int i = 0;
     
        if(tab[n] != 0)
            return tab[n];
     
        if(n == 1)
            return 1;
        else
        {
            tab[syracuse(n)] = calculNbreTermes(syracuse(n));
            nbreTermes = 1 + tab[syracuse(n)];
     
            return nbreTermes;
        }
    }
    Il marche bien pour une limite de 1000 mais au delà, j'ai une erreur de segmentation.
    Je n'arrive pas à en trouver l'origine.
    Un petit coup de pouce

  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
    Ton tableau est beaucoup trop gros. Alloue plutôt de la mémoire dynamiquement (malloc).

  3. #3
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Sans parler de la taille de ton tableau, ton erreur vient du fait que tu fais un joli dépassement.
    Je m'explique, ta fonction syracuse retourne n/2 si le nombre est pair, donc là pas de problème, mais elle retourne 3*n+1 quand ton nombre est impair. Dès que ton indice arrive à environ N/3 tu vas accéder aux indices plus grands que ton tableau

    Note que tu peux fortement améliorer ton code. Le but étant de mémoriser les nombres où tu es déjà passé en mettant le nombre d'opérations nécessaires pour arriver à 1.

    Bon courage

  4. #4
    Expert confirmé
    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
    Par défaut
    Tu risques aussi des problèmes liés aux appels récursifs de calculNbreTermes() dont il est sans doute difficile d'estimer la profondeur.

  5. #5
    Membre confirmé

    Inscrit en
    Octobre 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 69
    Par défaut
    Sans parler de la taille de ton tableau, ton erreur vient du fait que tu fais un joli dépassement.
    Effectivement, mais même en résolvant ce problème, j'avais toujours une erreur de segmentation qui provenait du fait que le type int ne pouvait stocker certains résultats de calculNbreTermes(). Donc, j'ai utilisé des unsigned long long à la place.
    Voici le code final
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    #define N 1000001
     
    static unsigned long long tab[N];
     
    unsigned long long syracuse(unsigned long long);
    unsigned long long calculNbreTermes(unsigned long long);
     
    int main(int argc, char * argv[])
    {
        int i = 0, max = 0;
        unsigned long long nbreTermes = 0, maxNbreTermes = 0;
     
        for(i = 1; i < N; ++i)
        {
            nbreTermes = calculNbreTermes(i);
            if(nbreTermes >= maxNbreTermes)
            {
                maxNbreTermes = nbreTermes;
                max = i;
            }
        }
     
        printf("Max = %d\n", max);
        printf("Nbre de termes = %lld\n", maxNbreTermes);
     
        return 0;
    }
     
    unsigned long long syracuse(unsigned long long n)
    {
        if(n % 2 == 0)
            return n / 2;
        else 
            return 3 * n + 1;
    }
     
    unsigned long long calculNbreTermes(unsigned long long n)
    {
        if(n == 1)
            return 1;
        else
        {
            if(n < N && tab[n] != 0)
                return tab[n];
            if(n < N)
            {
                tab[n] = 1 + calculNbreTermes(syracuse(n));
                return tab[n];
            }
            else
                return 1 + calculNbreTermes(syracuse(n));
        }
    }
    Le résultat est 837799 qui donne une suite de 525 termes
    Merci

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

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