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 :

allocation strucure et pointeur


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut allocation strucure et pointeur
    Bonjour, je suis nouveau dans se site et je me permet de vous exposer mon problème, Voici les différentes question de l'exercice :

    Nous souhaitons manipuler une structure de données constituée d'un tableau de pointeurs sur des structures de type Element(type défini dans la première question de cet énoncé).Cette structure de données sera donc de type Element **.
    Nous appelons taille de cette structure de données la taille de son tableau de pointeurs. Nous appelons k-ème élément de cette structure de données la structure dont l'adresse figure dans la case d'indice k du tableau de pointeur de cette structure de données.

    1. Écrire le code permettant de définir une structure de nom Element qui comporte deux champs de type int et de noms c1 etc2.

    Ma réponse ( je ne suis pas sur pour la notation des pointeurs) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef struct Element ** {
               int a,b;
               char* c1,c2;} Element;
    2.Écrire la fonction de prototype Element **creer_structure(int n) qui permet d'allouer et d'initialiser un telle structure de données de taille n. Cette fonction doit initialiser tous les champs des structures de type Element à 0 et retourner la structure de données allouée. On prendra soin d'éviter toute erreur de segmentation .

    Ma reponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Element **creer_structure(intn){
     
                   Element **tab = malloc(n*sizeof(Element));
     
                   if (tab == NULL){ 
                           printf("Probleme d'allocation \n");
                           return NULL;}
     
                   for(int i =0; i <=n;i++){
                        tab[i] = 0; }
                   return tab;
    }
    3.Écrire la fonction de prototype void liberer_structure(Element **sd, int n) qui permet de libérer l'espace mémoire occupé par la structure de données sd de taille n. Vous prendrez garde que votre fonction ne présente pas de risque de fuite de mémoire.

    Pour ca, je sais qu'il faut utiliser free() mais je sais pas comment l'utiliser xD.

    4.Écrire la fonction de prototype void modifier_element_dans_structure(Element **sd, int n,int k, int a,int b) qui permet d'affecter respectivement les valeurs a et b aux champs c1 et c2 du k-ème élément de la structure de données sd de taille n. Vous prendrez garde que votre fonction ne puisse pas générer d'erreur de segmentation.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 548
    Points
    10 548
    Par défaut
    Citation Envoyé par akhma Voir le message
    Element qui comporte deux champs de type int et de noms c1 etc2.

    Ma réponse ( je ne suis pas sur pour la notation des pointeurs) :

    typedef struct Element ** {
    int a,b;
    char* c1,c2;
    } Element;
    J'ai ri

    Espèce de gros béta :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef struct s_element  /*<- tu peux donner n'importe quel nom */ {
               int c1, c2;
    } Element;

    Citation Envoyé par akhma Voir le message
    if (tab == NULL){
    printf("Probleme d'allocation \n");
    return NULL;}
    Ouais ce n'est pas génial : il manque quand même un booléen pour dire si la création s'est bien passée et qu'on peut lire le tableau retourné. Mais la signature et le retour sont imposés.

  3. #3
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 460
    Points : 6 064
    Points
    6 064
    Par défaut
    Bonjour,

    Ta réponse à la question 1 ne compile pas. À terme, le plus simple serait que tu aies un compilateur C chez toi. En attendant, tu peux utiliser un compilateur en ligne. Il y en a plusieurs. En voici un :
    http://www.compileonline.com/compile_c_online.php

    Réponse à la question 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef struct Element {
        int c1, c2;
    } Element;
    [Edit]Doublé par foetus pour la réponse à la question 1.[/Edit]

    Pour la question 2, pour commencer, il manque une étoile après Element :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Element **tab = malloc(n*sizeof(Element*));
    En effet, il faut allouer un tableau de n pointeurs, donc chaque "case" du tableau doit avoir la taille d'un pointeur.

    Toujours dans la question 2, la suite du code ne respecte pas la consigne. La consigne ne demande pas que chaque pointeur du tableau soit nul. Chaque pointeur doit pointer vers un nouvel élément Element (à allouer) dont c1 et c2 valent 0. Je te laisse écrire le code et vérifier qu'il compile.

    Pour la question 3, voici un lien vers la FAQ C sur l'allocation dynamique de la mémoire :
    https://c.developpez.com/faq/?page=L...que-de-memoire

    Ce lien ne contient pas directement le code qui répond à la question, mais il explique, entre autres, comment utiliser free.

  4. #4
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut Reponse
    Tout d'abord, merci beaucoup pour vos réponse.

    Donc pour la question 2 voici se que j'ai modifier :

    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
    typedef struct s_element{int c1, c2;} Element;
     
    Element **creer_structure(int n){
     
                   Element **sd = malloc(n*sizeof(Element*));
     
                   if (tab == NULL){ 
                           return NULL;}
     
                   for(int i =0; i <=n;i++){
                        sd -> c1 = 0;
    		    sd -> c2 = 0; 
    		}
                   return sd;
    }
    Puis pour la question 3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void liberer_structure(Element **sd, int n){
     
                    **sd = **creer_structure(int n);
     
                    free(**sd);
    }
    Pour la question 4, je n'ai pas trop d'idée.

  5. #5
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut
    Code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct s_element{int c1, c2;} Element;
    Code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Element **creer_structure(int n){
     
                 Element **sd = malloc(n*sizeof(Element*));
     
                 if (tab == NULL){
                       return NULL;}
     
                 for(int i =0; i <=n;i++){
                       sd -> c1 = 0;
                       sd -> c2 = 0;
                 }
                 return sd;
    }
    Puis pour la question 3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void liberer_structure(Element **sd, int n){
     
                  **sd = **creer_structure(int n);
     
                  free(**sd);
    }

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 629
    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 629
    Points : 30 859
    Points
    30 859
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Je remarque que malgré ton MP, tu as quand-même réussi à trouver comment créer un topic.

    Citation Envoyé par akhma Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Element **creer_structure(int n){
     
                 Element **sd = malloc(n*sizeof(Element*));
     
                 if (tab == NULL){
                       return NULL;}
     
                 for(int i =0; i <=n;i++){
                       sd -> c1 = 0;
                       sd -> c2 = 0;
                 }
                 return sd;
    }
    Moui...
    C'est quoi "tab" en ligne 2 ??? Et à quoi sert de boucler sur "i" si "i" n'est pas utilisé dans la boucle ???
    Par ailleurs cette fonction a pour but de créer un tableau de n "Element". Donc il te faut allouer n pointeurs oui ; puis il te faut ensuite allouer chaque pointeur de ce tableau pour que chaque pointeur du tableau de pointeurs puisse, lui, stocker un "Element". Ce qu'a dit d'ailleurs Pyramidev.

    Citation Envoyé par akhma Voir le message
    Puis pour la question 3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void liberer_structure(Element **sd, int n){
     
                  **sd = **creer_structure(int n);
     
                  free(**sd);
    }
    Mouais. Là c'est du grand n'importe quoi. Pourquoi en effet créer la structure dans la fonction alors que celle-ci est sensée libérer une structure déjà créée ailleurs. Et tu penses vraiment qu'on te ferait écrire une fonction juste pour qu'elle appelle free() ??? Visiblement aucune réflexion quoi.

    Accessoirement, une convention veut que les types que l'on crée se nomment "t_xxx" pour ne pas les confondre ensuite avec des variables. Et aussi pour pouvoir utiliser le nom pour les variables justement. Parce que si tu veux créer une variable de type Element comment tu vas l'appeler ? "element" ??? => Element element en effet ça sera super clair et super lisible !!!
    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]

  7. #7
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut
    Merci pour ta réponse, en faite je ne comprend comment faire pour que chaque pointeur pointe vers un nouvel élément Element (à allouer) avec c1 et c2 valent 0

  8. #8
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut
    Je crois que c'est devenu un tout petit plus clair

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Element **creer_structure(int n){
     
                 Element **sd = malloc(n*sizeof(Element*));
     
                 for(int i=0;i<=n:i++){
    /* A partir d'ici je ne suis pas trop sur*/
                        *sd[i] = malloc(n*sizeof(Element));
                        sd[i] -> c1 = 0;                  
                        sd[i] -> c2 = 0;      
     
     
                 }
                 return sd;
    }

  9. #9
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 610
    Points : 1 534
    Points
    1 534
    Par défaut
    Hello,

    Ligne 7: inutile d'allouer la taille nécessaire à n structures, une seule suffit sd[i]=malloc(sizeof(Element));.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  10. #10
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut
    Et pour la question 3, j'ai penser a faire une boucle for pour libérer chaque Element dans le tableau.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void liberer_structure(Element **sd, int n){
     
                  for (i=0 ; i<=n ; i++){   
                       free(*sd[i]);
                  }
     
                  free(**sd);
    }

  11. #11
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut
    Citation Envoyé par edgarjacobs Voir le message
    Hello,

    Ligne 7: inutile d'allouer la taille nécessaire à n structures, une seule suffit sd[i]=malloc(sizeof(Element));.

    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
    /*Question 1*/
    typedef struct s_element{int c1, c2;} Element;
     
    /* Question 2 */
    Element **creer_structure(int n){
     
                 Element **sd = malloc(n*sizeof(Element*));
     
                 for(int i=0;i<=n:i++){
    /* A partir d'ici je ne suis pas trop sur*/
                        *sd[i] = malloc(sizeof(Element));
                        sd[i] -> c1 = 0;                  
                        sd[i] -> c2 = 0;      
     
     
                 }
                 return sd;
    }

  12. #12
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2018
    Messages : 10
    Points : 3
    Points
    3
    Par défaut
    Es ce que quelqu'un pourrait m'éclairer si il ya une erreur sil vous plait

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 629
    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 629
    Points : 30 859
    Points
    30 859
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par akhma Voir le message
    Es ce que quelqu'un pourrait m'éclairer si il ya une erreur sil vous plait
    Hého ! Il n'y a pas que toi dans le monde !!!

    Citation Envoyé par akhma Voir le message
    *sd[i] = malloc(sizeof(Element));
    sd[i] est un pointeur. C'est lui qui est alloué et non pas ce qui est pointé.

    Exemple: si je veux allouer et remplir un int, alors j'écrirai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int *pt;
    pt=malloc(int)
    (*pt)=1234;
    C'est "pt" qui est alloué, pas "*pt". Donc par analogie, si tu écris sd[i]->c1 = ... (équivalent à (*sd[i]).c1 = ...) alors écrire *sd[i]=malloc(...) ne peut pas être correct.
    Et pareil pour les free. C'est "sd" que tu alloues, c'est "sd" que tu libères.
    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]

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 548
    Points
    10 548
    Par défaut
    il manque aussi tous les tests
    Comme Sve@r : à la ligne 7, dans la fonction creer_structure, il faut virer l'étoile (d'ailleurs, je me demande si cela compile et si cela fait ce que tu crois ce que cela fait <- kamoulox)
    Et on peut utiliser l'arithmétique des pointeurs

    Non testé, non compilé :
    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
    Element** creer_structure(int size) {
        Element** array;
     
        if (size > 0) {
            array = malloc(size * sizeof(Element*));
     
            if (array != NULL) {
                Element** elt;
                Element*  new_elt;
     
                elt = array;
     
                do {
                    new_elt = malloc( sizeof(Element) );
     
                    if (new_elt != NULL) {
                        new_elt->c1 = 0;
                        new_elt->c2 = 0;
                    }
     
                    (*elt) = new_elt;
                    ++elt;
                    --size;
                } while(size > 0);
            }
        } else {
            array = NULL;
        }
     
        return array;
    }
     
     
    void liberer_structure(Element** array, int size){
        if ((array != NULL) && (size > 0)) {
            Element** elt = array;
     
            do {
                if ((*elt) != NULL) {
                    free( (*elt) );
    //              (*elt) = NULL;
                }
     
                ++elt;
                --size;
            } while(size > 0);
        }
     
        free(array);
    //  array = NULL; <- useless
    }

  15. #15
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 629
    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 629
    Points : 30 859
    Points
    30 859
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par foetus Voir le message
    il manque aussi tous les tests
    Oh là matelot, n'avançons pas trop vite. Quand il saura marcher, il pourra courir...

    Citation Envoyé par foetus Voir le message
    à la ligne 7, dans la fonction creer_structure, il faut virer l'étoile
    ligne 7 du post de 12h34, ligne 11 du post de 12h51

    Citation Envoyé par foetus Voir le message
    Et on peut utiliser l'arithmétique des pointeurs
    Oh là matelot (bis) !!! Tu veux nous l'exploser en plein vol ???
    Ceci dit, ton code d'allocation est excellent
    Juste un petit détail sur le size++ initial que je ne m'explique pas (si je veux allouer 1 élément, le do { alloc; size-- } while (size > 0) ou même plus simplement un while (size > 0) { alloc; size-- } semble me suffire sans avoir besoin d'incrémenter "size" au préalable.
    Et sinon moi je préfère sortir directement si erreur ce qui permet d'écrire le code "utile" sans tabulations pour pouvoir exploiter pleinement la ligne complète
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Element** creer_structure(int size) {
    	Element** array;
     
    	if (size <= 0) return NULL;
     
    	array = malloc(size * sizeof(Element*));
    	if (array == NULL) return NULL;
     
    	Element** elt;
    	Element*  new_elt;
    	... 
    }
    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]

  16. #16
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 460
    Points : 6 064
    Points
    6 064
    Par défaut
    Citation Envoyé par foetus Voir le message
    Non testé, non compilé :
    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
    Element** creer_structure(int size) {
        Element** array;
     
        if (size > 0) {
            array = malloc(size * sizeof(Element*));
     
            if (array != NULL) {
                Element** elt;
                Element*  new_elt;
     
                elt = array;
     
                ++size;
     
                do {
                    new_elt = malloc( sizeof(Element) );
     
                    if (new_elt != NULL) {
                        new_elt->c1 = 0;
                        new_elt->c2 = 0;
                    }
     
                    (*elt) = new_elt;
                    ++elt;
                    --size;
                } while(size > 0);
            }
        } else {
            array = NULL;
        }
     
        return array;
    }
     
     
    void liberer_structure(Element** array, int size){
        if ((array != NULL) && (size > 0)) {
            Element** elt = array;
     
            ++size;
     
            do {
                if ((*elt) != NULL) {
                    free( (*elt) );
    //              (*elt) = NULL;
                }
     
                ++elt;
                --size;
            } while(size > 0);
        }
     
        free(array);
    //  array = NULL; <- useless
    }
    Citation Envoyé par Sve@r Voir le message
    Ceci dit, ton code d'allocation est excellent
    En fait, dans creer_structure, pour vraiment gérer le cas où malloc( sizeof(Element) ) retourne NULL, il faudrait faire un free pour chaque précédent appel de malloc dans la fonction puis retourner NULL.
    Si on ne veut pas vraiment gérer les échecs d'allocation de mémoire alors, quand un malloc retourne NULL, on peut écrire un message dans la sortie d'erreur puis appeler exit() avec un code d'erreur.
    Dans les deux cas, c'est mieux que de retourner une structure partiellement allouée.

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 548
    Points
    10 548
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Juste un petit détail sur le size++ initial que je ne m'explique pas
    Effectivement, tu as raison, il faut les supprimer . Parce que size n'est pas 0-based, et donc zéro est bien une limite et non pas la dernière valeur.


    Citation Envoyé par Sve@r Voir le message
    Et sinon moi je préfère sortir directement si erreur ce qui permet d'écrire le code "utile" sans tabulations pour pouvoir exploiter pleinement la ligne complète
    C'est une habitude que j'ai pris (et si c'est possible) : 1 seul return final, pas de break (sauf dans les switch) ni de continue.
    Et effectivement l'indentation est primordiale et il faut s'accrocher un peu.


    Citation Envoyé par Pyramidev Voir le message
    Dans les deux cas, c'est mieux que de retourner une structure partiellement allouée.
    Effectivement tu as tout à fait raison. Mais
    • Il faut prendre des décisions. Un tableau partiellement alloué c'est le plus simple
    • Lorsqu'on prend un pointeur dans un tableau, il faut en théorie le tester
    • En théorie, si une allocation foire, toutes les autres qui suivent ont de grandes chances de subir le même sort ... et que ton programme sombre/ plante/ va sur Mars sans retour.

  18. #18
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 460
    Points : 6 064
    Points
    6 064
    Par défaut
    Citation Envoyé par foetus Voir le message
    En théorie, si une allocation foire, toutes les autres qui suivent ont de grandes chances de subir le même sort ... et que ton programme sombre/ plante/ va sur Mars sans retour.
    J'ai déjà vu un programme capable de faire ce qu'il faut malgré le manque de mémoire :
    • On essaie de faire une opération avec une implémentation rapide, mais qui consomme beaucoup de mémoire.
    • L'opération échoue à cause du manque de mémoire.
    • On libère la mémoire.
    • On refait l'opération avec une autre implémentation moins rapide, mais qui consomme peu de mémoire.

    C'était dans un programme C++, mais il est possible de faire la même chose en C.

    Un autre exemple serait celui d'une IHM où, quand une opération échoue sans que cela ne vienne d'une erreur de programmation, ce n'est pas forcément un bon prétexte pour arrêter l'appli.

    Bien sûr, en C, cela implique que tout le code soit écrit rigoureusement pour bien repropager l'échec d'allocation à l'appelant et bien libérer les ressources en remontant dans la pile, jusqu'à ce que l'on arrive dans le bout de code qui sait comment gérer le manque de mémoire sans repropager à l'appelant ou arrêter l'appli.

  19. #19
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 629
    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 629
    Points : 30 859
    Points
    30 859
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par foetus Voir le message
    C'est une habitude que j'ai pris (et si c'est possible) : 1 seul return final, pas de break (sauf dans les switch) ni de continue.
    Ah là là là là !!! La programmation "comme dans les livres de papi Dennis et grand-oncle Ken" (sans oublier Grand-Mère et son merveilleux café comme on n'en fait plus) !!!
    Ma mère (qui a été professeur de bridge) dit "un bon coup d'oeuil vaut mieux qu'une mauvaise impasse" sous-entendant que si on peut regarder dans le jeu de l'adversaire plutôt que tenter de supposer où se trouve le roi quand on doit choisir de jouer entre dame et as, il ne faut surtout pas s'en priver. Et j'avais un prof de sport qui disait "mieux vaut un bon <<mal acquis>> que deux <<tu l'auras peut-être honnêtement>>". Et les chinois disent "un bon dessin vaut mieux que 10000 mots".

    Donc si on mixe tout ça, on arrive à un truc ressemblant à "un bon break/continue/return bien placé vaut mieux que 10000 lignes pour le rattrapper"

    Citation Envoyé par Pyramidev Voir le message
    J'ai déjà vu un programme capable de faire ce qu'il faut malgré le manque de mémoire :
    • On essaie de faire une opération avec une implémentation rapide, mais qui consomme beaucoup de mémoire.
    • L'opération échoue à cause du manque de mémoire.
    • On libère la mémoire.
    • On refait l'opération avec une autre implémentation moins rapide, mais qui consomme peu de mémoire.
    Ah oui. Ca me rappelle "Kamelott livre V"
    Bon, on a deux solutions: on frappe et
    • soit il ouvre et on lui dit qu'on a besoin de lui
    • soit il n'ouvre pas et on re-frappe

    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]

  20. #20
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 460
    Points : 6 064
    Points
    6 064
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Donc si on mixe tout ça, on arrive à un truc ressemblant à "un bon break/continue/return bien placé vaut mieux que 10000 lignes pour le rattrapper"
    Étrange analogie. Comme tu es développeur Python, je m'attendais plutôt à ce que tu cites Flat is better than nested (The Zen of Python).
    En effet, les return, break et continue permettent d'éviter de mettre certains code dans des blocs if et donc d'éviter de les décaler vers la droite pour des raisons d'indentation.

Discussions similaires

  1. Allocation tableau de pointeur
    Par kaikait dans le forum Débuter
    Réponses: 4
    Dernier message: 24/04/2010, 22h59
  2. allocation dynamique et pointeur
    Par siempre dans le forum C
    Réponses: 3
    Dernier message: 29/11/2009, 22h35
  3. Réponses: 6
    Dernier message: 24/03/2006, 19h24
  4. [Pointeur] Allocation mémoire
    Par Rayek dans le forum Langage
    Réponses: 22
    Dernier message: 20/05/2005, 11h26
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 21h14

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