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 :

Connaître la taille d'un tableau


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 20
    Points : 13
    Points
    13
    Par défaut Connaître la taille d'un tableau
    Bonjour,
    Je cherche à connaître le nombre de cases dans un tableau pour en afficher le contenu. Mon souci, c'est que toutes les "cases" n'ont pas la même taille, puisqu'il s'agit d'un tableau dont le contenu est dynamiquement alloué.
    Du coup, la méthode habituelle du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define LENGTH(x) (sizeof(x) / sizeof(x[0]))
    ne fonctionne pas bien.

    Suis-je obligé de compter le nombre d'allocations lors de la création du tableau, ou existe-t-il une méthode pour retrouver la taille de ce dernier. La FAQ évoque des méthodes spécifiques.

    Le code (il s'agit de lister un répertoire, mettre cette liste dans un tableau et la retourner)
    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
     
    int
    countdir(const char *path)
    // return number of files in path
    {
     
        int num = 0;
        struct dirent *ent = NULL;
        DIR *d = opendir(path);
        if (d == NULL)
            perror("Open dir");
     
        while ((ent = readdir(d)) != NULL)
            num++;
        closedir(d);
        return num;
    }
     
    char ** 
    listdir(const char *path)
    {
        struct dirent *ent = NULL;
        char **dirlist = NULL;   
        int i;
     
        DIR *d = opendir(path);
        if (d == NULL)
            perror("Open dir");
     
        // Allocate number of files
        dirlist = malloc(sizeof(char*) * countdir(path));
     
        // Put file names in dirlist
        rewinddir(d);
        while ((ent = readdir(d)) != NULL)
        {
            // Allocate enough place for filename
            dirlist[i] = malloc( sizeof(char) * (strlen(ent->d_name)+1) );
            strcpy(dirlist[i], ent->d_name);
            i++;
        }
        closedir(d);
     
        return dirlist;
        // free dirlist!!!
    }
    Des erreurs ne sont pas exclues au passage...

  2. #2
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Tu fais du full dynamique, donc, comme avec les char, je te conseille d'ajouter 1 case supplémentaire à ton 1er malloc (celui là : dirlist = malloc(sizeof(char*) * countdir(path));), et d'y mettre NULL.
    Ainsi tu sauras que tu as fini de lister quand tu arrives sur l'adresse NULL !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int nb_dirs;
     
    nb_dirs = countdir(path);
    dirlist = malloc(sizeof(char*) * (nb_dirs + 1));
    dirlist[nb_dirs] = NULL;
    Tu n'as plus qu'à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(dirlist[i] != NULL)
    EDIT : en dynamique, il faut toujours allouer une case en plus, et y mettre une valeur qui servira de repère (donc souvent 0, NULL '\0').
    Ou alors tu dois connaitre la taille exacte, et propager celle-ci via une variable ou une structure.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 20
    Points : 13
    Points
    13
    Par défaut
    Ah oui, c'est pas bête du tout de faire comme ça!
    À présent j'étais parti sur une structure. Je me demande lequel est le plus propre?
    Est-ce "mal" d'utiliser une structure uniquement pour 2 variables?

    EDIT : Dans mon cas, pour libérer la mémoire de chaque liste, une structure semble plus appropriée pour s'y retrouver je crois. Il suffit de la passer à une fonction qui fera les free

  4. #4
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Il n'y a pas vraiment de plus "propre" ou "sale".
    C'est vraiment une méthode ou une autre !

    Avantage de la structure : tu peux faire un for sur une variable locale plutôt que de tester une valeur en mémoire.

    Avantage du tableau : code un tout petit peu moins lourd, car pas besoin de vérifier la structure pour comprendre quel membre fait quoi.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Metalman Voir le message
    Avantage de la structure : tu peux faire un for sur une variable locale plutôt que de tester une valeur en mémoire.
    Autre avantage, tu peux rajouter une troisième variables lors d'une future évolution sans avoir à repasser sur tes malloc (si tu alloues avec un sizeof(structure))
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  6. #6
    Membre à l'essai
    Inscrit en
    Janvier 2011
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 20
    Points : 13
    Points
    13
    Par défaut
    Merci pour tout vos conseils!

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Thuban Voir le message
    Est-ce "mal" d'utiliser une structure uniquement pour 2 variables?
    Salut
    Pas spécialement. Une structure est un mécanisme permettant d'associer plusieurs (donc au-moins 2) éléments disparates. Par exemple "nom+prenom" ou "nom+age" ou "jj+mm+aaaa" ou etc etc etc. Si tes 2 variables vont ensemble dans ta logique c'est mieux de les associer dans une structure manipulable plutôt que de te les trimbaler individuellement.
    Perso moi dans mes alloc dynamiques j'utilise une structure à 3 variables
    1) la zone allouée
    2) le nb d'éléments utilisés
    3) la taille réellement allouée
    Et je fais un realloc de N chaque fois que la valeur en 2 atteint celle stockée en 3. Ca offre plus de souplesse (si gros ordi je définis N très gros, si petit ordi je définis N très petit)

    Citation Envoyé par Thuban Voir le message
    EDIT : Dans mon cas, pour libérer la mémoire de chaque liste, une structure semble plus appropriée pour s'y retrouver je crois. Il suffit de la passer à une fonction qui fera les free
    Exactement !!!
    Mon Tutoriel sur la programmation «Python»
    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
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Je conseil également la structure, je n'utilise que cette méthode et elle a vraiment l'avantage de pouvoir évoluer sans devoir changer ton code et offre réellement plus de souplesse, code un peu plus lourd mais je trouve plus robuste.

    Par contre il faut penser un peu autrement quant à l'implémentation des fonctions qui vont gérer ta structure. Pour faire ça bien je te propose mes habitudes de programmation :

    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
    typedef struct
    {
       int      *  tab;
       size_t      nb_elems;
     
       /* Et d'autres membres par rapport à ce que tu as besoin. */
    }
    TaStructure;
     
     
    /* Creation. */
    TaStructure * TaStructure_new (size_t nb_elems);
     
    /* Destruction. */
    void TaStructure_free (TaStructure ** st);
     
    /* Redimensionnement. */
    void TaStructure_resize (TaStructure * st, size_t new_size);
    Voilà un exemple de schéma que tu pourrais suivre. J'utilise en fait toujours le nom de l'objet (la structure) comme préfixe dans le nom de mes fonctions, cela est très pratique si tu fait un code relativement gros et qui comporte plusieurs fichiers, un peu comme en POO si tu préfères et ça te fait un code carrément plus propre.

    Dans mes exemples et comme je fait d'habitude, j'alloue également dynamiquement la structure elle-même d'où la fonction de création qui renvoie un pointeur. Dans la fonction de destruction, je libère donc tous les membres alloués dynamiquement mais également la structure, d'où le fait que je transmet à la fonction l''adresse du pointeur pour faire ceci à la fin de la fonction TaStructure_free
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    free (*st);
    *st = NULL;
    Et pourquoi pas imaginer également une fonction comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void TaStructure_add_value (TaStructure * st, int val, size_t index);
    Certes plus lourd à utiliser qu'une simple opération d'affectation dans le code directement mais pourquoi pas, tu as tout un éventail de possibilité qui s'ouvre devant toi
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Dans mes exemples et comme je fait d'habitude, j'alloue également dynamiquement la structure elle-même d'où la fonction de création qui renvoie un pointeur
    Pourquoi faire ? Pourquoi ne pas définir dans le main un TaStructure toto puis passer &toto à toutes les fonctions qui auront besoin d'accéder au contenu ??? A quoi sert ce malloc supplémentaire ? Surtout que faire un malloc(1) semble un peu absurde...
    Mon Tutoriel sur la programmation «Python»
    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
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Pourquoi faire ? Pourquoi ne pas définir dans le main un TaStructure toto puis passer &toto à toutes les fonctions qui auront besoin d'accéder au contenu ??? A quoi sert ce malloc supplémentaire ? Surtout que faire un malloc(1) semble un peu absurde...
    Question d'habitude par rapport au projet sur lequel je travaille depuis plusieurs mois maintenant. J'en utilise par plusieurs dizaine et à la fin, centaine sans aucun doute donc, pas trop le choix je suppose car la pile est d'une taille limitée. Je veux bien que pour une ou deux (façon de parler hein ) on peut se passer de système mais quand on tape dans du lourd il faut voir les choses sous un autre angle.

    Après c'est sûr, pour ce sujet là et pour une seule structure oui, on peut très bien passer par une variable locale dont on transmet l'adresse aux différentes fonctions.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

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

Discussions similaires

  1. [Tableau]comment connaitre la taille d'un tableau à 2 dimensions
    Par Kyti dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 22/04/2005, 10h27
  2. Changer la taille d'un tableau déjà initialisé
    Par totofweb dans le forum C++
    Réponses: 2
    Dernier message: 25/07/2004, 15h55
  3. taille d'un tableau
    Par monstour dans le forum ASP
    Réponses: 3
    Dernier message: 24/06/2004, 15h16
  4. Taille maximum de tableau en Delphi
    Par yannick37 dans le forum Langage
    Réponses: 5
    Dernier message: 03/03/2004, 13h18
  5. qbasic : taille d'un tableau
    Par clood200 dans le forum Basic
    Réponses: 2
    Dernier message: 16/09/2003, 07h26

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