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 :

création difficile d'une structure


Sujet :

C

  1. #1
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut création difficile d'une structure
    Bonjour,

    Voilà j'ai un petit soucis concernant une structure, je souhaiterais ajouter un tableau de chaînes de caractères.

    Voici ma structure dans mon fichier.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
     
     
    typedef struct tab
    {
        char **table;
        int len;
    } tab;
     
    void ajouter(tab *tableau, char *ligne);
     
    #endif
    J'ai ensuite créer une fonction ajouter dans mon fichier.c

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void ajouter(tab *tableau, char *ligne)
    {
        tableau->table[tableau->len] = ligne;
        tableau->len++;
    }
    Ma fonction pour créer un nouveau tableau

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    tab *create()
    {
        tab *new = malloc(sizeof(tab));
        new->len = 0;
        return new;
    }
    et un main pour tester

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main(void)
    {
        tab *T = create();
        ajouter(T, "Bonjour");
        afficher(T);
        return 0;
    }
    Apparemment ça bug dans la fonction ajouter, j'ai pas de message d'erreur (ça compile), mais avec gdb, ça stoppe dans la fonction.

    Bref il doit y avoir un soucis dans la syntaxe ou une incompréhension de ma part

    Je vous remercie pour votre aide...

    P.S Il y a sans doute une autre façon de faire ce genre d'exercice, mais je m'entraîne aux structures.

    P.S2 La syntaxe me paraissant la plus logique était

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tableau->table[tableau->len][] = ligne;
    Mais le compilateur n'a pas aimé
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  2. #2
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Salut,

    partons de ta structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
     
     
    typedef struct tab
    {
        char **table;
        int len;
    } tab;
     
    #endif
    Elle contient len, je suppose la longueur en char* de table, et table que tu vas utiliser comme un tableau de char*.
    Tu crées une fonction d'allocation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    tab *create()
    {
        tab *new = malloc(sizeof(tab));
        new->len = 0;
        return new;
    }
    Il te manque, a priori, l'allocation de table.
    Je dis a priori car tu peux gérer ça dans la fonction d'ajout.

    Donc si tu veux ajouter une chaine il te faut faire de la place dans table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    if (tab->len==0) {
      // le premier élément crée la table
      tab->table= malloc(sizeof(char*));
      // on ajoute l'élément
      tab->table[0] = strdup(ligne);
      tab->len=1;
    } else {
      // on étend table
      tab->table=realloc(tab->table,(tab->len+1)*sizeof(char*));
      // on ajoute l'élément
      tab->table[tab->len] = strdup(ligne);
      tab->len++;
    }

    Il faut évidemment rajouter la gestion des erreurs d'allocations, ce code est tapé à la volée et peut contenir des erreurs.

    Ce n'est pas très optimisé de réallouer par morceau de 1 ... tu peux essayer de garder une capacité en plus de la longueur. Tu pourrais allouer par tranches plus grandes que 1.
    J'utilise strdup, cela permet de rendre les données indépendantes de la source, au lieu de faire un copie de pointeur il y a une copie de contenu dans un nouvel espace.
    N'oublie pas d'implémenter la libération de la mémoire (vachement important quand même !).

  3. #3
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Pour commencer la déclaration de la structure n'est pas conforme. Ce qui est en rouge est de trop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct tab
    {
        char **table;
        int len;
    } tab;

  4. #4
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Elle contient len, je suppose la longueur en char* de table, et table que tu vas utiliser comme un tableau de char*.
    Ah je t'arrêtes tout de suite, len est la longueur de tab et non de table

    @gerald3d

    Merci j'ai retiré mais la même erreur persiste

    Je place le code en entier après modification, il doit pas y avoir grand chose.

    Ma modification (j'ai tenté), le rajout de la fonction strcpy dans la fonction ajouter

    test.c

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "test.h"
     
    void ajouter(tab *tableau, char *ligne)
    {
        strcpy(tableau->table[tableau->len], ligne); /* Modification */
        tableau->len++;
    }
     
    void afficher(tab *tableau)
    {
        int i=0;
        for(; i<tableau->len; i++)
        {
            printf("ligne --> %s", tableau->table[i]);
        }
        tableau = NULL;
        free(tableau);
    }
     
    tab *create()
    {
        tab *new = malloc(sizeof(tab));
        new->table = NULL;
        new->len = 0;
        return new;
    }
     
    int main(void)
    {
        tab *T = create();
        char test[] = "Bonjour";
        ajouter(T, test);
        afficher(T);
        return 0;
    }
    test.h

    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
    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
     
     
    typedef struct
    {
        char **table;
        int len;
    } tab;
     
    void ajouter(tab *tableau, char *ligne);
    void afficher(tab *tableau);
    tab *create();
     
     
    #endif
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Ah je t'arrêtes tout de suite, len est la longueur de tab et non de table

    Hum, je pense que tu te représentes mal les choses. Un tab a une longueur constante la taille d'un entier plus la taille d'un pointeur ; len est bien le nombre de chaine contenue dans table.
    À moins que tu ne cherches à créer un tableau de tab ?

    Quelle genre de structure essayes-tu de créer ?

    { {"bonjour",0}, {"comment",1} , {"vas",2}, {"tu",3} }
    ou
    { {"bonjour", "comment", "vas", "tu"} , 4}

  6. #6
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Ha j'ai trouvé mon erreur, j'ai effectivement oublié d'allouer de la mémoire pour mon table, mais dans la fonction ajouter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tableau->table[tableau->len] = malloc(strlen(ligne) * sizeof(char));
    Du coup ça fonctionne nickel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void ajouter(tab *tableau, char *ligne)
    {
        tableau->table[tableau->len] = malloc(strlen(ligne) * sizeof(char));
        strcpy(tableau->table[tableau->len], ligne);
        tableau->len++;
        free(tableau->table[tableau->len]);
    }
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  7. #7
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Hum, je pense que tu te représentes mal les choses. Un tab a une longueur constante la taille d'un entier plus la taille d'un pointeur ; len est bien le nombre de chaine contenue dans table.
    À moins que tu ne cherches à créer un tableau de tab ?
    Bah en fait je recherche à faire une liste de chaînes de caractères
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  8. #8
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Un autre moyen serait d'essayer de construire une liste chaînée. Ca va t'obliger à manipuler les pointeurs pour la créer et la gérer.
    Une fois qu'elle est opérationnelle tu peux t'en servir de brique pour construire ton application actuelle.

    Ca reste un très bon exercice pour appréhender les pointeurs.

  9. #9
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void ajouter(tab *tableau, char *ligne)
    {
        tableau->table[tableau->len] = malloc(strlen(ligne) * sizeof(char));
        strcpy(tableau->table[tableau->len], ligne);
        tableau->len++;
        free(tableau->table[tableau->len]);
    }
    Deux erreurs en gras :
    la première tu oublies le 0 terminal (classique ) La chaine "bonjour" est de longueur 7 mais prend 8 octets {'b','o','n','j','o','u','r',0} -> il faut toujours réserver strlen + 1

    tu libères de la mémoire que tu viens d'allouer (ou presque, voir le len++) -> je ne pense pas que cela soit ce que tu désires.

  10. #10
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Une deque? Oui je l'ai déjà fais et réussi, tu veux que je place mon code ici?

    Je voulais juste que ça devienne automatique, plus j'en fais et mieux c'est!



    la première tu oublies le 0 terminal (classique ) La chaine "bonjour" est de longueur 7 mais prend 8 octets {'b','o','n','j','o','u','r',0} -> il faut toujours réserver strlen + 1
    Hmmm... Si je comprend bien, le '\0' ne sera pas dans chacune des chaînes de caractères, en effet c'est gênant, merci pour l'info

    Pour le free je ne comprend pas, à l'exécution, j'ai pas de soucis, tout est affiché, je ne vois pas où tu veux en venir en fait

    donc mon code finalisé

    test.c

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "test.h"
     
    void ajouter(tab *tableau, char *ligne)
    {
        tableau->table[tableau->len] = malloc((strlen(ligne)+1) * sizeof(char));
        strcpy(tableau->table[tableau->len], ligne);
        tableau->len++;
        free(tableau->table[tableau->len]);
    }
     
    void afficher(tab *tableau)
    {
        int i=0;
        for(; i<tableau->len; i++)
        {
            printf("ligne %d --> %s\n", i, tableau->table[i]);
        }
    }
     
    tab *create()
    {
        tab *new = malloc(sizeof(tab));
        new->table = malloc(sizeof(char));
        new->len = 0;
        return new;
    }
     
    int main(void)
    {
        tab *T = create();
        char test[] = "Bonjour";
        char test1[] = "Coucou";
        ajouter(T, test);
        ajouter(T, test1);
        afficher(T);
        T = NULL;
        free(T);
        return 0;
    }
    test.h

    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
    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
     
     
    typedef struct
    {
        char **table;
        int len;
    } tab;
     
    void ajouter(tab *tableau, char *ligne);
    void afficher(tab *tableau);
    tab *create();
     
     
    #endif
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  11. #11
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Une deque? Oui je l'ai déjà fais et réussi, tu veux que je place mon code ici?

    Je voulais juste que ça devienne automatique, plus j'en fais et mieux c'est!





    Hmmm... Si je comprend bien, le '\0' ne sera pas dans chacune des chaînes de caractères, en effet c'est gênant, merci pour l'info
    strlen ne compte pas le '\0', mais tu dois allouer de l'espace pour lui car strcpy l'utilises, d'où le +1 pour lui réserver de la place.
    strdup fait le boulot pour toi
    plus secure -> utilise strndup ou strncpy

    Pour le free je ne comprend pas, à l'exécution, j'ai pas de soucis, tout est affiché, je ne vois pas où tu veux en venir en fait
    Pourquoi fais-tu un free ? Sur quoi fais-tu le free ?
    Ce genre de ligne est une erreur qui peut ne pas se déclarer tout de suite et provoquer ensuite de gros plantages => debug garanti
    Dans ton cas tu accèdes à de la mémoire non encore allouée ... et si tu déplaces le len++, à de la mémoire fraichement allouée que tu risque d'utiliser par la suite.

    Il faut toujours vérifier que l'allocation a réussi.

  12. #12
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Pourquoi fais-tu un free ? Sur quoi fais-tu le free ?
    Eh bien c'est peut-être là où je pense que l'on n'est pas très clair.

    Je fais un free() sur tableau->table[i] et non sur tableau->table

    strlen ne compte pas le '\0', mais tu dois allouer de l'espace pour lui car strcpy l'utilises, d'où le +1 pour lui réserver de la place.
    strdup fait le boulot pour toi
    plus secure -> utilise strndup ou strncpy
    Merci pour l'info je vais modifier ça
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  13. #13
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Eh bien c'est peut-être là où je pense que l'on n'est pas très clair.

    Je fais un free() sur tableau->table[i] et non sur tableau->table
    Où et quand l'as-tu alloué ?

  14. #14
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void ajouter(tab *tableau, char *ligne)
    {
        tableau->table[tableau->len] = malloc((strlen(ligne)+1) * sizeof(char)); /* Allocation mémoire */
        strcpy(tableau->table[tableau->len], ligne);
        tableau->len++;
        free(tableau->table[tableau->len]); /* libération quand on en a plus besoin */
    }
    C'est vrai que j'ai toujours du mal à placer mes free(), ça continue apparemment
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  15. #15
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Il ne faut faire un free que si tu as fait un malloc avant (ou pour certaines fonctions qui le font pour toi comme strdup).
    Faire un free sur un espace mémoire non alloué n'est pas une bonne idée.
    Comme dans ton main tu fais un T=NULL, suivi d'un free(T). Faire un free sur un NULL est moyen.
    L'idée est si tu as une fonction qui crée une sdd, tu dois avoir une fonction qui libère ce que tu as alloué. À ton Create devrait correspondre un Destroy et en gros à toute allocation dans le Create tu dois avoir un free dans le Destroy.

    table est de type pointeur sur pointeur de char, il faut aussi revoir le malloc sur table.

    D'après toi, si tu lis 15 chaines, ou alloues-tu de l'espace pour ces 15 chaines ?

  16. #16
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Il ne faut faire un free que si tu as fait un malloc avant (ou pour certaines fonctions qui le font pour toi comme strdup).
    Faire un free sur un espace mémoire non alloué n'est pas une bonne idée.
    Mais je comprend pas, je ne l'ai pas fais un malloc avant ?

    Comme dans ton main tu fais un T=NULL, suivi d'un free(T). Faire un free sur un NULL est moyen.
    Ok j'enregistre...

    L'idée est si tu as une fonction qui crée une sdd, tu dois avoir une fonction qui libère ce que tu as alloué. À ton Create devrait correspondre un Destroy et en gros à toute allocation dans le Create tu dois avoir un free dans le Destroy.
    Ok je comprend, supprimer toutes les chaines dans ma structure et libérer avec free(), un peu comme j'ai fais avec ma deque
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  17. #17
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void ajouter(tab *tableau, char *ligne)
    {
        tableau->table[tableau->len] = malloc((strlen(ligne)+1) * sizeof(char)); /* Allocation mémoire */
        strcpy(tableau->table[tableau->len], ligne);
        tableau->len++;
        free(tableau->table[tableau->len]); /* libération quand on en a plus besoin */
    }
    imagine len=12 quand tu entres dans ta fonction
    tableau->table[12]= <allocation>
    <copie>
    len=13
    libération de table[13] mais table[13] jamais alloué !!!!

    Autre question tu manipules tableau->table, mais où l'as-tu alloué ? Dans le Create ? En fait, qu'as-tu alloué dans Create ?

  18. #18
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Ha ok, j'avais pas pigé! je cherchais plus compliqué

    Autre question tu manipules tableau->table, mais où l'as-tu alloué ? Dans le Create ? En fait, qu'as-tu alloué dans Create ?
    4 octets?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  19. #19
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Si on reprend ta structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct
    {
        char **table;
        int len;
    } tab;
    En sachant que tu veux lire plusieurs ligne, les stocker dans table et en garder le nombre dans len :
    on commence par un petit #define pour commencer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define MAXLIGNES 1000
    On prévoit le code pour un maximum de 1000 lignes.

    Ensuite :
    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
     
    tab* Create()
    {
      tab* t = malloc(sizeof(tab)); // on alloue de la place pour une structure tab
      // insérer ici la gestion des erreurs d'allocation
      t->len=0 ; // au départ on a aucune chaine
      t->table= malloc(MAXLIGNES*sizeof(char*)); // on alloue de la place pour au maximum MAXLIGNES lignes
      // insérer ici la gestion des erreurs d'allocation
     
      // le boulot est fait -> on renvoie tout
      return t;
    }
     
    void Destroy(tab* t)
    {
      if (t==NULL) return; // certainement une erreur, mais bon ...
      // on libère la mémoire allouée pour table
      free(t->table);
      // on libère la mémoire allouée à la strcture 
      free(t);
    }
    Tu vois un malloc = un free (en sens inverse).
    Tu comprends cette démarche ?

  20. #20
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Oui j'avais donc bien compris, j'avais alloué pour char soit 4 octets.

    J'ai modifié cela!

    Le malloc, un free je connaissais, mais placer le free, ça a toujours été le bordel, mais j'ai pigé maintenant grâce à toi, enfin je pense

    Merci pour tes explications, j'ai beaucoup avancé dans mon projet pendant qu'on discutait et j'ai un soucis autre maintenant, je vais réécrire un nouveau sujet si je ne m'en sors pas, mais je vais chercher un peu avant.

    Merci pour vos explications
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

Discussions similaires

  1. Réponses: 0
    Dernier message: 04/04/2012, 19h08
  2. Réponses: 0
    Dernier message: 26/07/2011, 14h20
  3. Création d'une structure dynamique
    Par jbat dans le forum API, COM et SDKs
    Réponses: 17
    Dernier message: 14/04/2008, 15h55
  4. Création d'un vecteur à partir d'une structure
    Par lilyla dans le forum MATLAB
    Réponses: 4
    Dernier message: 13/02/2008, 13h45
  5. Réponses: 20
    Dernier message: 11/07/2006, 17h11

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