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 :

[alloc] Lecture d'un fichier


Sujet :

C

  1. #1
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 885
    Par défaut [alloc] Lecture d'un fichier
    Bonjour

    Voilà fort longtemps que je n'ai plus fait de C. Donc, veuillez d'ores et déjà excuser la naïveté sans doute de la question.
    Voici mon problème, je veux lire un fichier et stocker une (grosse) partie de son contenu en mémoire. Je précise que c'est un fichier texte :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    void setSequence(char *filename){
    	int SIZE = 512;
    	char ligne[SIZE];
    	char *Sequence = (char *)malloc(SIZE*sizeof(char));
    	if(Sequence==NULL){
    		fprintf(stderr, "Memory allocation error !\n");
    		exit(2);
    	}
    	FILE *file = fopen(filename, "r");
    	if(file==NULL){
    		fprintf(stderr, "Can not access to %s\n", filename);
    		exit(3);
    	}
    	while(fgets(ligne, sizeof ligne, file)){
          if(ligne[0] != '>')
          {
             strcat(Sequence, ligne);
             char *tmp = (char *)malloc(SIZE*sizeof(char));
             if(tmp==NULL){
    		 	fprintf(stderr, "Memory allocation error !\n");
    		 	exit(2);
    		 }
             SIZE*=2;
             tmp = Sequence;
             Sequence = (char *)realloc(Sequence, SIZE*sizeof(char));
             if(Sequence==NULL){
    		 	fprintf(stderr, "Memory allocation error !\n");
    		 	exit(2);
    		 }
             Sequence = tmp;
             free(tmp);
          }
       }
       	printf("%s\n", Sequence);
    }
    Or, à l'exécution de mon code, je reçois l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    *** glibc detected *** double free or corruption (!prev): 0x0804a008 ***
    Abandon
    Bon, apparemment, il y a un stress dans mes allocations mémoires. Quelle peut bien être mon erreur ?
    Merci d'avance de vos réponses.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  2. #2
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 885
    Par défaut
    Rebonjour

    J'ai corrigé le corps de ma boucle while en introduisant quelques commentaires :
    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
     
    while(fgets(ligne, sizeof ligne, file)){
          if(ligne[0] != '>')
          {
             strcat(Sequence, ligne);
             printf("%s\n", Sequence);
             SIZE*=2;
             Sequence = (char *)realloc(Sequence, SIZE*sizeof(char));
             /*char *tmp = (char *)malloc(SIZE*sizeof(char));
             if(tmp==NULL){
    		 	fprintf(stderr, "Memory allocation error !\n");
    		 	exit(2);
    		 }
             SIZE*=2;
             tmp = Sequence;
             Sequence = (char *)realloc(Sequence, SIZE*sizeof(char));
             if(Sequence==NULL){
    		 	fprintf(stderr, "Memory allocation error !\n");
    		 	exit(2);
    		 }
             Sequence = tmp;
             free(tmp);*/
          }
       }
    De cette manière, au bout d'un certain temps, j'ai quand même un segfault. A mon avis, je dois peut être solliciter trop de mémoire lors du realloc ?

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  3. #3
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 885
    Par défaut
    Bon apparemment, je sollicite trop de mémoire, je vais procéder à une autre opération

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  4. #4
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 885
    Par défaut
    :trouve:
    C'était parce que je prenais une valeur trop importante de mémoire :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define VALUE 512
     
    void setSequence(char *filename){
    	long SIZE = VALUE;
    	char ligne[VALUE];
    	char *Sequence = (char *)malloc(SIZE*sizeof(char));
    	if(Sequence==NULL){
    		fprintf(stderr, "Memory allocation error !\n");
    		exit(2);
    	}
    	FILE *file = fopen(filename, "r");
    	if(file==NULL){
    		fprintf(stderr, "Can not access to %s\n", filename);
    		exit(3);
    	}
    	while(fgets(ligne, sizeof ligne, file)){
          if(ligne[0] != '>')
          {
             strcat(Sequence, ligne);
             SIZE=SIZE+VALUE;
             Sequence = (char *)realloc(Sequence, SIZE*sizeof(char));
             if(Sequence==NULL){
    		 	fprintf(stderr, "Memory allocation error !\n");
    		 	exit(2);
    		 }
          }
       }
       printf("%s\n", Sequence);
    }
    C'est mieux ainsi.
    Merci à vous !

    @++

    GLDavid, autorésolveur
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  5. #5
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut Re: [alloc] Lecture d'un fichier
    Ok je vais venir descendre un peu ton premier code mais c'est pour ton bien, ne m'en veux pas trop

    Donc ton erreur venait d'une mauvaise gestion de tes pointeurs...

    Déjà quelques remarques sur ta programmation C:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	char *Sequence = (char *)malloc(SIZE*sizeof(char));
    On ne fait plus de cast après un malloc en C...
    Ensuite puisque c'est des char que tu veux, ceci suffit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	char *Sequence =malloc(SIZE);
    Ensuite, puisque c'est une taille fixe, effectivement, une déclaration statique est plus intelligente...


    Mais le vrai problème vient d'ici (j'ai viré les tests après les malloc/realloc):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
             strcat(Sequence, ligne);
             char *tmp = (char *)malloc(SIZE*sizeof(char));
     
             SIZE*=2;
             tmp = Sequence;
             Sequence = (char *)realloc(Sequence, SIZE*sizeof(char));
     
             Sequence = tmp;
             free(tmp);
    Tu viens d'allouer une zone mémoire pour tmp, tu perds cette adresse parce que tu copies la valeur du pointeur Sequence. Après le realloc, tu remets la valeur du pointeur tmp qui est maintenant sûrement invalide, du coup tu perds également la nouvelle zone mémoire de Sequence et ensuite tu fais un free sur tmp.

    En gros, en l'espace de 4 instructions, tu viens de rendre 2 variables inutilisables, de perdre 2 zones mémoires allouées dynamiquement et tu viens de faire un free sur un pointeur qui n'est plus valide...

    Il faudra réviser un peu ta gestion de pointeurs...

    Jc

  6. #6
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 885
    Par défaut
    En effet, j'ai grand besoin de revoir un peu les pointeurs.
    Faut dire, comme vu en préambule, que ça fait peut être.......2 ans que je n'ai plus fait de C. Trop habitué au Java, Perl et C++
    Mais bon, C doit être comme le vélo, ça s'oublie pas !

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par GLDavid
    :trouve:
    C'était parce que je prenais une valeur trop importante de mémoire :
    • La mémoire n'est pas libérée.
    • Le fichier n'est pas fermé.
    • Dépassement du tableau 'Sequence'

    Malgré mes corrections de base, ce code est buggé (débordement mémoire). Je l'ai instrumenté (LIM_PTR(), CHK_PTR) pour que tu puisses le constater et le corriger. Je recommande un mécanisme 'souple' comme mon module FSTR.

    Code manquant et FSTR ici :

    http://emmanuel-delahaye.developpez.com/clib.htm

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
     
    #include "ed/inc/sys.h"
     
    #define VALUE 512
     
    static int setSequence(char const *filename)
    {
       int ret = EXIT_SUCCESS;
     
       long SIZE = VALUE;
       char ligne[VALUE];
       char *Sequence = malloc(SIZE * sizeof * Sequence);
       if (Sequence != NULL)
       {
          FILE *file = fopen(filename, "r");
     
          LIM_PTR (Sequence, SIZE);
          CHK_PTR (Sequence, SIZE);
     
          if (file != NULL)
          {
             while (fgets(ligne, sizeof ligne, file) != NULL && ret == EXIT_SUCCESS)
             {
                if (ligne[0] != '>')
                {
                   strcat(Sequence, ligne);
                   CHK_PTR (Sequence, SIZE);
     
                   SIZE = SIZE + VALUE;
                   {
                      void *tmp = realloc(Sequence, SIZE * sizeof * Sequence);
                      if (Sequence != NULL)
                      {
                         Sequence = tmp;
                      }
                      else
                      {
                         fprintf(stderr, "Memory allocation error !\n");
                         ret = EXIT_FAILURE;
                      }
                   }
                }
             }
             printf("%s\n", Sequence);
             fclose (file), file = NULL;
          }
          else
          {
             perror(filename);
             ret = EXIT_FAILURE;
          }
          free(Sequence), Sequence = NULL;
          assert (file == NULL);
       }
       else
       {
          fprintf(stderr, "Memory allocation error !\n");
          ret = EXIT_FAILURE;
       }
     
       assert(Sequence == NULL);
       return ret;
    }
     
    int main (void)
    {
       char const *filename = "data.txt";
       setSequence(filename);
       return 0;
    }

  8. #8
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 885
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 885
    Par défaut
    Ok

    Merci Emmanuel pour ton aide.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

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

Discussions similaires

  1. Lecture d'un fichier .dbf
    Par San Soussy dans le forum Autres SGBD
    Réponses: 8
    Dernier message: 07/07/2004, 16h30
  2. Réponses: 6
    Dernier message: 02/09/2003, 15h12
  3. Lecture et ecriture fichier .ini
    Par despe dans le forum C
    Réponses: 6
    Dernier message: 23/07/2003, 20h40
  4. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 4
    Dernier message: 05/02/2003, 08h54
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

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