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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 18
    Par défaut Segmentation fault; pas d'idées
    Bonjour,

    J'ai plus d'idées pour mon problème.

    Merci pour votre aide.

    Y a-t-il quelque chose qui justifie une erreur de segmentation ?


    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    main()
    {
    int i=1,j=1;
    char *c2,*c3;
    char *c;
     
    c=0;
     
    c2=0;
    c3=0;
     
    char *a[65000][256];
    for(i=1;i<=65000;i++) {for(j=1;j<=256;j++)*a[i][j]=0;};
     
    i=1;
    j=1;
     
    FILE *fp=fopen("/sdcard/GDE.Main/tt.txt","a+");
    rewind(fp);
    do{
     
    fgets(c,1,fp);
    fseek(fp,1,SEEK_CUR);
    fgets(c2,1,fp);
     
     
    fseek(fp,-1,SEEK_CUR);
     
    if (c=="/t") j++;
    if (c=="/" && c2=="/n") i++;
    strcat(a[i][j],a[i][j]);
    strcat(a[i][j],c);
    }while (feof(fp)==0);
     
    fclose(fp);
     
    return 0;
    }
    Fichiers attachés Fichiers attachés

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

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    y'a un souci dès le début :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *a[65000][256];
    for(i=1;i<=65000;i++) {for(j=1;j<=256;j++)*a[i][j]=0;};
    c'est i=0;i< sinon tu vas taper en dehors de ton tableau.

    Ton autre problème c'est que tu crées un tableau de pointeur sans allocation mémoire.

    Plus simplement, que cherches-tu à faire avec ce code ? (qu'y a-t-il dans tt.txt)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 18
    Par défaut
    Bonjour Fregolo,

    Merci de répondre.

    Le fichier est de type export texte excel.

    Il s'agit d'une lecture sur un mobile comme les tableurs sont pas térribles

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 18
    Par défaut
    (ce qui est de l'allocation évidemment je m'en suis rendu compte cependant je n'y arrive pas sans déclencher des erreurs de conversion de type)

    Le code proposé est celui qui ne provoque pas d'erreur de compilation.

  5. #5
    Membre émérite 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 : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Salut.

    Citation Envoyé par Aurel5477 Voir le message
    Le code proposé est celui qui ne provoque pas d'erreur de compilation.
    Oui, c'est syntaxiquement correct.
    M'enfin bon...

    Citation Envoyé par Aurel5477 Voir le message
    (ce qui est de l'allocation évidemment je m'en suis rendu compte cependant je n'y arrive pas sans déclencher des erreurs de conversion de type)
    Pourtant il n'y a rien de compliqué.
    Si T est le type des données pour lesquelles tu veux allouer de la mémoire et n le nombre d'éléments que tu veux crééer, les expressions génériques suivantes permettent d'allouer correctement la mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    T *p = (T *) malloc(n * sizeof(T));
    T *q = (T *) calloc(n, sizeof(T));
    La différence entre les deux, c'est que pour la première, on se contente de réserver l'espace mémoire nécessaire, alors que pour la seconde on initialise cette zone avec des 0.

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

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    La question qu'il faut se poser est : est ce que la déclaration est correcte
    Représente 3 dimensions

    Si tu cherches à stoker 65000 ligne de 256 caractères (max), la bonne déclaration est :
    Et ca va simplifier énormément les choses

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 18
    Par défaut
    ça n'a effectivement pas l'air compliqué, mais j'ai toujours une conversion invalide char* à char quand je mets la forme 1 dans ma boucle de la ligne 16

  8. #8
    Membre émérite 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 : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Maintenant concernant ton code...

    Tout d'abord, la première chose qui me frappe, c'est que tu écris du code C, mais tu postes sur le forum C++.
    Ce serait bien de résoudre cette petite incohérence...
    Bon, pour la suite, je vais supposer que tu veux faire du C, et que tu t'es trompé de forum (ou que tu as voulu ratisser large).


    Ensuite, comme l'a souligné fregolo52, tu utilises des pointeurs sans allocation.
    Que ce soient c, c2, c3, ou les 65000*256 éléments de a, ce sont des pointeurs qui ne pointent pas sur une zone dédiée (réservée).
    Ça peut être voulu, mais ce n'est pas le cas ici.

    Le premier paramètre de la fonction fgets indique à quelle adresse écrire les données lues depuis le flux.
    La zone mémoire pointée doit avoir été allouée (réservée), et être suffisamment grande pour recevoir toutes les données (d'où l'utilité du deuxième paramètre).
    Or, non seulement tu n'as pas alloué de mémoire (statiquement ou dynamiquement) pour stocker ces données, mais en plus la valeur du pointeur que tu passes en paramètre est NULL !
    Autrement dit, aux lignes 25 et 27, tu essaies d'écrire à l'adresse 0x0, ce qui n'est évidemment pas une adresse valide.
    Pas étonnant que tu obtiennes une erreur de segmentation...


    Quand on y regarde de plus près, à ces mêmes lignes, tu ne lis qu'un seul caractère à la fois.
    Dans ce cas, tu n'as peut-être pas besoin d'utiliser un pointeur sur un caractère, mais directement un caractère, et passer l'adresse de ce caractère à la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char c;
    (...)
    fgets(&c, 1, fp),
    Cela résoudrait le problème d'allocation mémoire...

    Et puisque tu lis caractère par caractère, tu aurais peut-être également intérêt à utiliser fgetc à la place de fgets.
    Il faut juste se souvenir que fgetc retourne la constante EOF une fois arrivée à la fin du flux.
    Mais bon, c'est à toi de voir ce qui est le plus simple pour toi.


    Je crois que les tests des lignes 32 et 33 ne font pas ce que tu attends.
    L'expression (c == "/t") signifie :
    Tester si l'adresse pointée par c est la même que l'adresse de la chaîne de caractères (constante) "/t"
    ce qui est différent de :
    Tester si la chaîne de caractères pointée par c est égale à la chaîne de caractères "/t"
    Si tu veux tester l'égalité entre deux chaînes de caractères, tu es obligé d'utiliser la fonction strcmp.


    Pour les lignes 34 et 35, c'est exactement le même problème que pour les lignes 25 et 27.
    Le premier paramètre de strcat doit pointer sur une zone mémoire (allouée) suffisamment grande pour contenir tous les caractères de la chaîne de caractère qui résultera de l'opération.
    Autrement dit, pour l'expression strcat(dest, src), la taille de la zone mémoire pointée par dest doit être supérieure ou égale à strlen(dest) + strlen(src) + 1 (ne pas oublier le caractère NUL à la fin de la chaîne).


    Sinon, quelques remarques en vrac :
    • Tu as vraiment besoin de c3 ? Tu ne l'utilises pas dans ton code...
    • Quand on ouvre un flux, on vérifie qu'il a bien été ouvert avant de l'utiliser (si ce n'est pas le cas, fopen retourne NULL).
    • Pourquoi tu ouvres ton flux avec le mode "a+" vu que tu n'écris jamais dedans ? "r" serait suffisant.
    • [Edit]De plus, en te contentant d'ouvrir le flux en lecture seule, tu n'as pas besoin d'appeler rewind pour replacer le curseur au début du flux.[/Edit]
    • Pourquoi tu reviens en arrière après tes lectures ? Vu comment c'est fait, le premier caractère lu d'une itération sera le même que le dernier caractère lu de l'itération précédente...
    • Vu que tu reviens en arrière avant de tester si tu es à la fin du fichier, tu ne risques pas de l'atteindre... Par contre, tu peux y arriver au milieu de ta boucle, et je ne sais pas trop ce qu'il se passe quand tu essaies de te déplacer dans ton flux par rapport à la position courante alors que tu as déjà atteint la fin du flux...

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