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 :

Problème d'allocation dynamique


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2019
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Problème d'allocation dynamique
    Bonjour,
    Je commence le C et je travaille sur un exercice d'allocation dynamique dont le but est d'afficher les mots contenu dans fichier ("strings.txt"). Ces mots seront contenus dans une structure composé d'un tableau dynamique et d'une valeur qui correspond à la longueur du mot.

    Voici le programme :

    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
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
     
    #define STR_MAX 100
     
     
    void* malloc(size_t nombreOctetsNecessaires);
     
     
    struct string
    {
        char str[STR_MAX] ;
        int len ;
    } ;
     
     
    struct string * lit_fichier(char *nom_fichier, int *nb)
    {
        FILE *f ;
        int i = 0 ;
        int j = 0 ;
        char *chaine = NULL ;
        struct string *tab = NULL ;
     
        f = fopen(nom_fichier,"r") ;
     
        printf("avant comptage %d %d \n", i, *nb) ;
        /* On compte le nombre de mots */
        fgets(chaine, 20, f) ;
        printf("%s ",chaine) ;
        while ( (i<*nb) && ( fgets(chaine, 20, f) ) != NULL) {
            printf("pendant comptage %d \n", i) ;
            i++ ;
        }
     
        *nb = i ;
        printf("apres comptage %d \n", *nb) ;
     
        /* Retour au début du fichier */
        fseek(f, 0, SEEK_SET) ;
     
        /* Allocation dynamique et vérification */
        tab = malloc(*nb * sizeof(char*)) ;
     
        if (tab == NULL ){
            fprintf(stderr,"Allocation impossible \n");
            exit(EXIT_FAILURE);
        }
        printf("avant lecture dans lecture %d \n", *nb) ;
        /* Lecture du fichier */
        while  ( (j < *nb) && ( fgets(chaine, 20, f) != NULL ) ){
            strcpy(tab[j].str, chaine) ;
            tab[j].len = strlen(tab[j].str - 1) ;
            j++ ;
        }
        printf("apres lecture dans lecture %d \n", j) ;
     
     
        fclose(f) ;
        return tab ;
    }
     
     
    void affichage(struct string tab[], int longueur)
    {
        int i ;
     
        for ( i = 0 ; i < longueur ; i++ ) {
            printf("%s   (%d) \n" , tab[i].str, tab[i].len) ;
        }
    }
     
     
    int main(int argc, char *argv[])
    {
        FILE *f ;
        struct string *tableau ;
        int nb = 10 ;
     
        /* Ouverture du fichier */
        if ( argc == 1 ) {
            fprintf(stderr, "Il me faudrait un nom de fichier ...\n") ;
            return 1 ;
        }
     
        f = fopen(argv[1], "r") ;
     
        if ( f == NULL ) {
            fprintf(stderr, "Impossible de lire le fichier [%s].\n", argv[1]) ;
            return 2 ;
        }
     
        fclose(f) ;
     
        printf("avant lecture %d \n", 1);
        tableau = lit_fichier(argv[1], &nb) ;
        printf("après lecture %d \n", 2);
        affichage(tableau, nb) ;
        printf("après affichage %d \n",3) ;
     
        /* Libération de la mémoire */
        free(tableau) ;
        tableau = NULL ;
    }

    Je n'ai pas d'erreur à la compilation, mais pourtant en l'exécutant, j'obtiens ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    avant lecture 1 
    avant comptage 0 10 
    Segmentation fault: 11
    Le programme ne rentre pas dans la 1ère boucle de "lit_fichier" alors que la condition sur i est bonne et qu'il y a des choses à lire dans le fichier.
    Je ne comprends pas d'où vient mon erreur
    Une explication ?

    Merci d'avance !

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 017
    Points : 5 088
    Points
    5 088
    Par défaut
    Bonjour,

    ligne 24, on voit bien que chaine vaut NULL.
    ligne 31, on passe chaine à la fonction fgets en lui disant que c'est un buffer capable de recevoir au moins 20 caractères.
    Boom

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2019
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Mais je ne vois pas comment "initialiser" chaine autrement qu'en lui donnant la valeur NULL. Comment est-ce que je pourrais m'en sortir ?

  4. #4
    Responsable Systèmes


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    11 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 11 858
    Points : 26 595
    Points
    26 595
    Par défaut
    Mais je ne vois pas comment "initialiser" chaine autrement qu'en lui donnant la valeur NULL. Comment est-ce que je pourrais m'en sortir ?
    Avec malloc. Ou initialiser chaine comme ceci :
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2019
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Ça marche, merci beaucoup !

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 7 683
    Points : 21 851
    Points
    21 851
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par AuBar Voir le message
    Mais je ne vois pas comment "initialiser" chaine autrement qu'en lui donnant la valeur NULL. Comment est-ce que je pourrais m'en sortir ?
    Ton souci c'est que tu n'as pas bien compris la façon de faire. On ne te demande pas d'initialiser chaine (d'ailleurs pourquoi initialiser un truc qui va être rempli 3 lignes plus bas), on te demande de garantir que chaine aura bien la place pour stocker 20 caractères.
    D'où la solution de chrtophe qui te propose d'utiliser malloc (allocation mémoire) ou bien de définir chaine comme un tableau tout prêt (et non plus un pointeur pointant sur rien).
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    novembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : novembre 2019
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    J'avais aussi mal compris l'exercice : il était uniquement nécessaire que le tableau soit alloué dynamiquement et non chaine.
    Donc la bonne réponse était que chaine devait être un tableau de taille fixe !

  8. #8
    Responsable Systèmes


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    11 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 11 858
    Points : 26 595
    Points
    26 595
    Par défaut
    Je rajouterais qu'en C, une chaine de caractères est en fait un tableau de char devant ce terminer par \0. Si on y accède via un pointeur, celui-ci pointera sur le premier élément de ce tableau. Pas sûr que tu es déjà vu les pointeurs.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 20/09/2009, 18h40
  2. problème d'allocation dynamique.
    Par watiero dans le forum C++
    Réponses: 15
    Dernier message: 18/02/2008, 19h06
  3. Problème d'allocation dynamique
    Par addsomemusic dans le forum Fortran
    Réponses: 3
    Dernier message: 11/01/2008, 11h45
  4. Problème d'allocation dynamique
    Par Hybrix dans le forum C++
    Réponses: 4
    Dernier message: 09/12/2007, 23h12
  5. Question sur les problèmes d'allocation dynamique
    Par slylafone dans le forum C++
    Réponses: 23
    Dernier message: 25/10/2004, 15h18

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