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; pas d'idées


Sujet :

C++

  1. #41
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 364
    Points : 5 378
    Points
    5 378
    Par défaut
    Question bête, on ne sait pas à qui on a affaire !!

    Tu es quoi : étudiant ? jeune bidouilleur en herbe (qui apprend en fouillant sur le web) ? ...

    Tout ça pour éviter de te perdre avec une réponse super technique que tu comprendrais mal.

  2. #42
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 18
    Points : 0
    Points
    0
    Par défaut
    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    main()
    {
    int i=0;
    int j=0;
    int k=0;
    //int l=1;
     
    char c=0;
    char**a;
    //char *s[20];
    //a[65][25]=new (char);
    for(j=1;j<=25;j++){
    a[i][j]=(char)malloc(65*25*sizeof(char));
    }
    for(i=1;i<=65;i++){
    a[i]=(char*)malloc(sizeof*a[i]*25);
    }
    i=1;
    j=1;
    FILE *fp=fopen("/sdcard/GDE.Main/tt.txt","r");
    //FILE *f=tmpfile();
     
    for(i=1;i<=1625;i++){
     
    char c;
    c=fgetc(fp);
    printf("%c",c);
    if (isprint(c)==0 && isspace(c)!=0)
    {
    j++;
    k=1;
    //l=0;
    }
    //if (toascii(c)==atoi("013"))j++;
    if (isprint(c)!=0 && isspace(c)!=0){
    k++;
    //l=0;
    }
    if(feof(fp)!=0)break;
    //a[j][k]=(char*)calloc(10,sizeof(char));
    //if (l=0){
    //a[j][k]=(char*)realloc(10,sizeof(char));
    //a[j][k]=new char;
    //l=1;
    //}
    //s[j]=(char*)malloc(20);
    //(const char*)c=(const char*)malloc(1);
    //strcat(a[j][k],(const char*)c);
    //strcat(a[j][k],c);
    //sscanf(a[j][k],"%10s",s[1]);
    if (isspace(c)==0){
     
    sprintf(a[j][k],"%s%c",a[j][k],c);
    }
    };
    //printf("%c",s[1]);
    printf("%s",a[3][2]);
    printf("(%d",j);
    printf("/%d)",k);
    //fclose(f);
    fclose(fp);
     
    return 0;
    }
    Bonjour,

    Je suis toujours bloqué J'ai laissé toutes mes pistes en commentaires sinon je me rends compte qu'à force de modifications ça ne ressemble plus à rien et on ne sait plus d'où vient telle ou telle variable déclarée non utilisée et des morceaux de codes ineptes se trouvent postés aussi.
    Pour cibler dans ce fouillis:si je mets l'allocation dans la boucle principale:j'écrase le début de ma chaine;j'alloue en dehors comme ici je me retrouve avec un char* (???) dans sprintf qui n'est pas accepté.
    Je ne peux pas conditionner l'allocation dans la boucle principale non plus.

  3. #43
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    En effet, on ne voit plus trop ce que le programme est censé faire...
    Un petit détail : indenter le code permet une meilleure lisibilité, en particulier pour ceux qui ne l'ont pas écrit.

    Autre chose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char**a;
    for (j = 1; j <= 25; j++) {
        a[i][j] = (char) malloc(65 * 25 * sizeof(char));
    }
    for (i = 1; i <= 65; i++) {
        a[i] = (char*) malloc(sizeof * a[i] * 25);
    }
    Tu alloues la dimension 2 avant la dimension1.
    Tu penses vraiment que ça peut fonctionner ?
    En supposant que la première partie ne fasse pas planter violemment le programme, dans la deuxième partie tu perds les adresses que tu viens de récupérer.
    De toutes façons, tes allocations sont fausses...

    Pour allouer un tableau dynamique à deux dimensions, de NB_LIGNES lignes et NB_COLONNES et de type T, on le fait comme ceci :
    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
    T **tab;
     
    // Allocation des lignes
    tab = (T **) malloc(NB_LIGNES * sizeof(T *));
     
    // Allocation des cellules
    for (i = 0; i < NB_LIGNES; ++i)
        tab[i] = (T *) malloc(NB_COLONNES * sizeof(T));
     
    // À présent, on peut accéder à tab[i][j].
     
    (...)
     
    // Ne pas oublier de libérer les ressources lorsque l'on n'en a plus besoin !!!
    for (i = 0; i < NB_LIGNES; ++i)
        free(tab[i]);
    // L'accès à tab[i][j] est illégal !!!
    free(tab);
    tab = NULL; // Facultatif, juste pour être sûr que personne n'accédera à la valeur caduque de tab.
    Bon, d'après ce que j'ai compris, je peux te proposer une solution.
    Je pars du principe que le nom du fichier est stocké dans la variable char const *fichier.
    De plus, je suppose que le tableau char ***mots a été correctement alloué (statiquement ou dynamiquement) sur les deux premières dimensions, et qu'il est suffisamment grand pour contenir chaque mot de chaque ligne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    FILE *fp = fopen(fichier, "r");
    if (fp == NULL) {
        fprintf(stderr, "Impossible d'ouvrir le fichier %s.\n", fichier);
        exit(EXIT_FAILURE);
    }
    Il est important de vérifier qu'un flux a bien été ouvert avant de tenter de l'utiliser.
    Sinon, attends-toi à une belle erreur de segmentation lorsque tu voudras lire ou écrire des données...

    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
    // Variables d'accès aux éléments du tableau
    int ligne = 0;
    int colonne = 0;
     
    // Chaîne de caractères temporaire pour stocker les mots en cours de lecture
    // Taille maximale à adapter aux besoins
    char tmp[MAX_LONG];
    int index = 0; // Position dans la chaîne temporaire
     
    // Variable stockant le dernier caractère lu
    int c;
     
    // Lecture du fichier...
    c = fgetc(fp);
    while (c != EOF) { // fgetc retourne EOF lorsque la fin du fichier est atteinte
     
        if (c == '\n') {
            // On est à la fin d'une ligne
            ++ligne;
            colonne = 0;
        }
     
        else if (isspace(c)) {
            // On a lu un caractère d'espacement, donc on est à la fin d'un mot
            tmp[index] = '\0'; // Le caractère NUL indique la fin de chaîne
            mots[ligne][colonne] = (char *) malloc((index + 1) * sizeof(char)); // Allocation de la mémoire nécessaire dans le tableau => ne pas oublier de désallouer en fin de programme !
            strcpy(mots[ligne][colonne], tmp);
            ++colonne;
            index = 0;
        }
     
        else {
            // On a lu un caractère normal, on le place à la fin de la chaîne temporaire
            tmp[index] = c;
            ++index;
        }
     
        c = fgetc(fp);
    }
    Je prends le parti de n'allouer les chaînes du tableau à la bonne taille.
    Mais cela nécessite de la connaître au préalable.
    C'est pourquoi j'ai besoin d'une chaîne de caractères annexe pour stocker temporairement les mots lu ; on suppose qu'elle est suffisamment grande pour contenir chacun d'entre eux.
    Une fois un mot lu, on peut déterminer sa longueur, et ainsi allouer l'espace juste nécessaire pour le stocker.
    Il ne reste plus qu'à le copier dans le tableau.

    Lors de la libération des ressources, il faudra faire attention aux chaînes qui n'ont finalement pas été allouées.

    Une autre possibilité est de déterminer à l'avance une longueur qu'aucun mot ne dépassera, et allouer chaque chaîne du tableau avec cette longueur.
    On évite ainsi de passer par une chaîne auxilliaire, mais on va réserver de la place pour rien.

    Concernant la boucle while de lecture, on peut la transformer en une boucle do while équivalente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    do {
        c =  fgetc(fp);
        if (c != EOF) {
            // Traitements durant la lecture...
        }
    } while (c != EOF);
    D'un côté on écrit l'expression de mise à jour 2 fois, de l'autre c'est le test de fin de boucle.
    Comme tout bout de code dupliqué, c'est sujet à erreur, lors de modifications notemment.
    Aucune boucle n'est a priori plus sûre que l'autre.

    Voilà.
    À la fin de l'algo, tu obtiens dans mots[i][j] le (i+1)-ième mot de la (j+1)-ième colonne (s'il existe).
    En espérant que ça corresponde à ce que tu souhaitais...

    Ceci dit, il y a tout de même quelques restrictions.
    En plus des hypothèses posées au début, je suppose que le fichier suit la convention UNIX pour les fins de ligne, et qu'il n'y peut pas y avoir plusieurs caractères d'espacement à la suite.

Discussions similaires

  1. Réponses: 5
    Dernier message: 23/12/2009, 11h31
  2. Réponses: 5
    Dernier message: 09/06/2009, 10h30
  3. Problème : pas de segmentation fault ?!
    Par Loïc B. dans le forum C++
    Réponses: 3
    Dernier message: 05/11/2007, 17h08
  4. Réponses: 13
    Dernier message: 13/07/2004, 15h41
  5. Comment contrer la "segmentation fault" ?
    Par guillaume_pfr dans le forum C
    Réponses: 15
    Dernier message: 08/08/2003, 13h43

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