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

Affichage des résultats du sondage: Améliorer la bibliothèque standard au niveau de l'allocation dynamique?

Votants
10. Vous ne pouvez pas participer à ce sondage.
  • C'est une bonne idée

    1 10,00%
  • J'en vois pas l'utilité

    9 90,00%
C Discussion :

Allocation dynamique, discussion autour de la librairie standard


Sujet :

C

  1. #1
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Points : 38
    Points
    38
    Par défaut Allocation dynamique, discussion autour de la librairie standard
    Bonjour,

    Cette discussion viens en suite de celle-ci https://www.developpez.net/forums/d1...ire-d-origine/

    Résumé :

    Un code possible de realloc par @dalfab:
    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
    void *realloc( void *blocACopier , size_t nouvelleTaille ) {
       size_t  alloues = 0;     // bytes réservés
       size_t  taille = 0;      // bytes utilisables
       if ( blocACopier ) {
          alloues = ((size_t*)blocACopier)[-1]; // une structure possible ou une autre?
          taille  = ((size_t*)blocACopier)[-2];
          while ( nouvelleTaille > alloues  &&  la-zone-suivant-le-bloc-est-disponible ) {
             fusionner-le-bloc-avec-le-bloc-suivant-et-trouver-nouvelle-valeur-pour-'alloues'
             ((size_t*)blocACopier)[-1] = alloues;
          }
       }
       if ( nouvelleTaille > alloues ) {        // allocation nécessaire ailleurs
          void *tmp = malloc( nouvelleTaille ); //allocation d'une nouvelle zone mémoire et 2*size_t avant
          if ( !tmp ) return NULL;
          if ( blocAcopier ) {
             memcpy( tmp , blocACopier , taille );
             free( blocACopier );
             blocACopier = tmp;
          }
       }
       else { // assez ou trop grand
          if ( nouvelleTaille + TAILLE_HYSTERESIS < alloues ) { // trop grand
             couper-le-bloc-ne-garder-que-le-necessaire-et-trouver-nouvelle-valeur-pour-'alloues'
             ((size_t*)blocACopier)[-1] = alloues;
          }
          ((size_t*)blocACopier)[-2] = nouvelleTaille;  // noter la nouvelle taille utile
       }
       return blocACopier;
    }
    Pourquoi allez chercher les tailles d'allocation n'est pas standardisé?
    Citation Envoyé par @Jamatronic
    Pour interdire aux programmeurs d'aller consulter ces données et faire des bidouilles avec ?

    Si vous le faites, c'est à vos risques et périls.
    Citation Envoyé par @Médinoc
    Le fait est que le standard C ne prévoit aucun moyen de demander à l'implémentation la taille d'un bloc alloué. Choix délibéré ou oubli, je l'ignore.
    D'autres bibliothèques faisant de l'allocation de mémoire (comme les diverses de Windows) proposent de telles fonctions (LocalSize()/GlobalSize() pour LocalAlloc()/GlobalAlloc() (retournent la taille réelle du bloc, qui peut être plus grande que celle initialement demandée), HeapSize() pour HeapAlloc(), VirtualQuery() pour VirtualAlloc(), mais rien pour la mémoire allouée via CoTaskMemAlloc())

    Résultat, si tu fais un programme en C standard, c'est à toi de garder trace des tailles allouées (y compris, par exemple, en utilisant la tactique mentionnée par dalfab).
    Citation Envoyé par @Matt_Houston
    Quelle en serait l'utilité ? Ce serait imposer d'énormes contraintes au système d'allocation pour bien peu d'avantages offerts au programmeur au final.
    Citation Envoyé par @chrtophe
    malloc fonctionne sur des systèmes différents allant de Linux à MS-DOS. Il peut donc être logique que la façon dont la fonction gère l'allocation soit différente et qu'il ne faille pas "bricoler". C'est l'intérêt d'une fonction système, tu ne te préoccupe pas de son fonctionnement, tu lui donnes une (ou plusieurs) entrée(s) et tu attend un résultat en sortie.

    Tu peux toujours étudier le code source de la fonction.

    Ou plus facile d'accès un tuto comme celui-ci :
    http://www.inf.udec.cl/~leo/Malloc_tutorial.pdf
    Fin du résumé.

    Je comprend que ce soit le système qui gère l'allocation, que les fonctions soit simplement un dialogue avec lui. Et son intérêt! Comme cela c'est adaptable sur tout support. Ce qui m'embête c'est que l'on est pas accès à tout. Obligé le programmeur à enregistrer lui même les tailles quand il en a besoin alors que le système le sais très bien c'est pas terrible... J'ai aussi découvert que la fonction recalloc n'existe pas. Bref c'est un manque que je trouve dommage.

    Je ne vois pas en quoi cela pourrait ajouter d'énormes contraintes au système d'allocation, vu qu'il a déjà l'air de le faire? Où que ce serait meilleur d'interdire les programmeurs de jouer avec...

    C'est pour cela que j'aimerai vous poser la question suivante : Est ce qu'une amélioration de la bibliothèque standard sur l'allocation dynamique serait une bonne chose? Offrir une plus grande liberté au programmeur et une meilleur interaction avec le système.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Cela tient à la philosophie même du langage C: Celui-ci a été pensé pour la performance et pour offrir le maximum de liberté à l'implémentation. Ce qui soulève les problèmes suivants si on voulait rajouter une fonction getallocsize():
    • Pour des raisons de performance, d'alignement etc., la zone mémoire allouée peut être plus grande que la demande (par exemple, une taille arrondie aux 8 octets supérieurs). Quelle taille faudrait-il alors retourner? La vraie taille, comme le fait LocalSize() sous Windows, ou la taille demandée, comme le fait HeapSize?
    • Le premier cas peut poser des problèmes parce que malloc() n'initialise pas la mémoire qu'elle alloue, on risque donc un code qui demande X octets, les initialise, puis plus tard récupère la taille et croit que toute la zone est initialisée.
    • Le second cas oblige l'implémentation à mémoriser quelque part la taille demandée, qui peut être en plus de ses autres informations. D'où, utilisation de plus de mémoire pour chaque allocation, ralentissement de chaque allocation... malloc() est une fonction utilisée assez souvent pour que la performance puisse être un souci.

    Garder en mémoire la vraie taille demandée serait probablement moins gênant en C++, qui en a déjà besoin pour toutes les allocations de tableaux de types contenant un destructeur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Points : 38
    Points
    38
    Par défaut
    Bonjour @Médinoc,

    Citation Envoyé par Médinoc
    Cela tient à la philosophie même du langage C: Celui-ci a été pensé pour la performance et pour offrir le maximum de liberté à l'implémentation. Ce qui soulève les problèmes suivants si on voulait rajouter une fonction getallocsize():

    Pour des raisons de performance, d'alignement etc., la zone mémoire allouée peut être plus grande que la demande (par exemple, une taille arrondie aux 8 octets supérieurs). Quelle taille faudrait-il alors retourner? La vraie taille, comme le fait LocalSize() sous Windows, ou la taille demandée, comme le fait HeapSize?
    Le premier cas peut poser des problèmes parce que malloc() n'initialise pas la mémoire qu'elle alloue, on risque donc un code qui demande X octets, les initialise, puis plus tard récupère la taille et croit que toute la zone est initialisée.
    Le second cas oblige l'implémentation à mémoriser quelque part la taille demandée, qui peut être en plus de ses autres informations. D'où, utilisation de plus de mémoire pour chaque allocation, ralentissement de chaque allocation... malloc() est une fonction utilisée assez souvent pour que la performance puisse être un souci.

    Garder en mémoire la vraie taille demandée serait probablement moins gênant en C++, qui en a déjà besoin pour toutes les allocations de tableaux de types contenant un destructeur.
    D'après les informations que j'ai pu récupéré dans ce post https://www.developpez.net/forums/d1...ire-d-origine/
    Ce tutoriel http://www.inf.udec.cl/~leo/Malloc_tutorial.pdf et le code source de la glibc https://code.woboq.org/userspace/gli...l#_int_realloc

    Si j'ai bien compris c'est le second cas qui sera déjà utilisé.

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Précisons "qui est utilisé par la glibc dans la version que tu as étudiée."
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonsoir,
    Il faut surtout comprendre que l’allocation dynamique d’une mémoire avec malloc() dépend du système et de l’architecture sur lequel elle est implémentée et chaque système d'exploitation apporte de légères adaptations à la fonction pour leur système (je parle de malloc() parce que, realloc() se base sur les sous-routines de malloc() ou malloc() lui-même). Il y a donc des variantes sur certaines sous-routines de malloc() (et je suis d'avis avec @chrtophe à ce propos). De plus, les choses sont bien plus compliquées en réalité que vous ne le pensez. Comme ce que vous avez pu en déduire de vos recherches, la fonction malloc() s'appuie sur deux routines sbrk() et mmap() (la projection mémoire) avec divers algorithmes pour l'allocation de la mémoire (stratégie d’allocation mémoire). malloc() donne également la possibilité au développeur d'invoquer leur propre fonction dans les routines de malloc() pour par exemple déboguer, optimiser, etc. grâce aux points d’appel.

    Citation Envoyé par dalfab Voir le message
    Bonjour,
    En fait malloc(), calloc() et realloc() allouent au moins 8 octets de plus que demandés, stockent dans ces octets les tailles allouées, et retournent un pointeur augmenté de 8. Le format de ces données n'est pas standardisé, c'est pourquoi on ne doit pas y accéder. Un code possible
    Non, pas tout à fait. L'exemple de l'allocation mémoire de plus se base sur sbrk() et c'est justifier. malloc() fait appel à sbrk() (occasionnellement car il gère dès le départ un semble de bloc mémoire), mais sollicite plus de mémoire non pas pour stocker les tailles allouées, mais tout simplement pour en fournir immédiatement lors d'un second appel de malloc() , car sbrk() en réalité coûte cher en ressources, mais elle renvoie bien la taille mémoire demander. (En ce qui concerne la taille en octet ; cela est lié l'architecture "les alignements". C'est-à-dire que malloc() garantit un alignement mémoire correct pour pouvoir stocker n'importe quel type de données. L'alignement de ces données est effectivement tous les 8 octets sur une architecture 32 bits et sur des architectures 64 bits elle est fixée à 16 octets et donc le format de ces données est bien standardisé parce que la taille utilisée par exemple sur une architecture 32 bits permet de manipuler directement des entiers voire réels dans la mémoire et qui d'ailleurs correspond à la taille d'un double ou d'un long long int).

    Citation Envoyé par Médinoc Voir le message
    C'est un détail d'implémentation et rien ne garantie que ce soit vraiment le cas (un OS pourrait stocker ses tailles quelque part en espace Kernel à la place, voire les déduires de ses listes chaînées de blocs...).


    Le fait est que le standard C ne prévoit aucun moyen de demander à l'implémentation la taille d'un bloc alloué. Choix délibéré ou oubli, je l'ignore.
    D'autres bibliothèques faisant de l'allocation de mémoire (comme les diverses de Windows) proposent de telles fonctions (LocalSize()/GlobalSize() pour LocalAlloc()/GlobalAlloc() (retournent la taille réelle du bloc, qui peut être plus grande que celle initialement demandée), HeapSize() pour HeapAlloc(), VirtualQuery() pour VirtualAlloc(), mais rien pour la mémoire allouée via CoTaskMemAlloc())
    Résultat, si tu fais un programme en C standard, c'est à toi de garder trace des tailles allouées (y compris, par exemple, en utilisant la tactique mentionnée par dalfab).
    GLibC, met à disposition un bon nombre de sous-routines, et même dédier au débogage exemple de quelque routine:
    • La fonction malloc_info() qui permet de fournir une chaîne XML qui décrit exactement l’état actuel de l'implémentation de l'allocation mémoire
    • La fonction mallopt() permet d'ajuster les paramètres qui contrôlent le comportement des fonctions d'allocation de mémoire
    • La fonction malloc_get_state() enregistre l'état actuel de tous les allocation (malloc) dans une variables internes mais pas le contenu réel du tas ou de l'état de ces mémoire.
    • La fonction malloc_set_state() est l'inverse de la précédente elle restaure l'état de tous les allocation.
    • La fonction malloc_trim() libère ou tente de libérer de la mémoire en haut du tas en appelant sbrk().
    • La fonction malloc_usable_size() renvoie le nombre d'octets utiliser dans le bloc pointé par ptr , un pointeur sur un bloc de mémoire alloué par malloc() realloc() etc.. en clair il permet obtenir la taille du bloc de mémoire alloué à partir de tas.
    • etc..


    Personnellement amélioré la bibliothèque standard au niveau de l'allocation dynamique, je ne vois pas vraiment l'intérêt, mais apporter quelque optimisation subtile pourquoi pas, mais cela demande à revoir pas mal de choses. Cependant, je ne suis pas contre votre première idée "un exemple d'utilisation des fonction de re-allocation" s'ils n'existent pas.
    À bientôt.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  6. #6
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 434
    Points : 43 065
    Points
    43 065
    Par défaut
    Je pense que les fonctions citées par Sambia sont spécifiques à glibc et pas POSIX. Ce qui signifie qu'elle ne seront pas valables sous FreeBSD par exemple.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  7. #7
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    Je pense que les fonctions citées par Sambia sont spécifiques à glibc et pas POSIX. Ce qui signifie qu'elle ne seront pas valables sous FreeBSD par exemple.
    Raison pour laquelle, j'ai spécifié GlibC, mais aussi que l'on trouvera des variantes de malloc() qui dépendent bien de l'architecture machine et du système d'exploitation. Et à ce propos, l'implémentation de malloc() sous BSD (FreeBSD par exemple) est légèrement différente; j'irais même jusqu'à dire tout simplement, totalement différente mais attention pas sur tous les points mais les deux évoluent chacun de leur côté et c'est normal qu'il est ont leurs propre implémentation; D'ailleurs une des nombreuses raisons pour lequel je suis proud donor de FreeBSD.

    Sur les BSD (voir variantes de BSD) l'implémentation de malloc() prend un argument de plus, mais ne supporte pas ou n'implémente pas certaines fonctions de la Glib. malloc() de BSD par exemple prend en charge certaine sous routine et pas d'autre comme les storage allocation hooks, obstacks, etc. En tout point qui à choisir, j'opterais pour l'implémentation de la BSD qui est beaucoup plus performant en tout point que ceux de la Glib implémenté dans divers systèmes Linux ou GNU/Linux.

    Autre point que je n'ai pas évoqué pas mal de tutoriel s'appuie sur sbrk() voir mmap() voir les deux pour expliquer comment fonctionne l'allocation dynamique, mais ce n'est qu'un exemple expliquant plus ou moins le mécanisme d'allocation de certains systèmes ce n'est pas en réalité comme ça que sa marche pour se renseigner, il suffit de lire les sources des différentes implémentations pour comprendre.

    À bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  8. #8
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Points : 38
    Points
    38
    Par défaut
    Bonjour @sambia39,

    Merci beaucoup pour tes réponses, j'y vois plus clair à présent.

    Citation Envoyé par sambia39
    Personnellement amélioré la bibliothèque standard au niveau de l'allocation dynamique, je ne vois pas vraiment l'intérêt, mais apporter quelque optimisation subtile pourquoi pas, mais cela demande à revoir pas mal de choses. Cependant, je ne suis pas contre votre première idée "un exemple d'utilisation des fonction de re-allocation" s'ils n'existent pas.
    Revoir qu'elles choses et c'est à dire un exemple d'utilisation des fonction de re-allocation? Genre comme la FAQ que j'essaye de faire passer qui reste en stand-by https://www.developpez.net/forums/d1...loc-ca-marche/ ? Je pense d'ailleurs que je vais créer un nouveau post la dessus, je n'arrive pas à modifier mon premier message... J'ai envoyé un message aux admins, cependant il est resté sans réponse à ce jour. Il mettent du temps à répondre?

    Citation Envoyé par sambia39
    pour se renseigner, il suffit de lire les sources des différentes implémentations pour comprendre.
    Il y en as beaucoup? J'avoue que je débarque un peu. Je ne pensais pas qu'il puisse avoir autant de choses derrière le langage C.

    A bientôt

  9. #9
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par theludovyc Voir le message
    Revoir qu'elles choses et c'est à dire un exemple d'utilisation des fonction de re-allocation? Genre comme la FAQ que j'essaye de faire passer qui reste en stand-by https://www.developpez.net/forums/d1...loc-ca-marche/ ? Je pense d'ailleurs que je vais créer un nouveau post la dessus, je n'arrive pas à modifier mon premier message... J'ai envoyé un message aux admins, cependant il est resté sans réponse à ce jour. Il mettent du temps à répondre?
    A bientôt
    Peut-être pas comme votre exemple, mais plutôt une approche plus simple avec des explications ; expliquant utilisation de realloc dans divers contextes. (allocation , agrandissement, réduction et libération mémoire). Attention, la réduction ou realloc libère et tronque les données dues au fait que l'on fournisse une taille inférieur a la taille d'origine peut échouer, mais en temps normal une réduction est possible.

    Exemple ci-dessous qui permet de voir que realloc peut être utilisé a la fois pour allouer redimensionnée ou libérer de la mémoire.
    Code C : 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
     
     
     
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    int main( void ){
     
        char *p = NULL;        
        char *pp = NULL;
     
        errno = 0;
     
        /*
        *   Allocation mémoire avec realloc
        */
        if( NULL == ( p = realloc( NULL, sizeof(*p) * 10 ) ) ){
            (void)fprintf(stderr, "Erreur(%d)\t:%s\t:%s\n",
                errno, "Erreur allocation dynamique",
                strerror(errno) );
            return EXIT_FAILURE;
        }
     
        memset(p, 0x41, (sizeof(*p) * 10) );
        (void)fprintf(stderr, "%s\n", p );
     
        /*
        *   Agrandissement de la mémoire
        */
        if( NULL == ( pp = realloc(p, (sizeof(*p) * 20)) ) ){
            free(p);
            p = NULL;
            (void)fprintf(stderr, "Erreur(%d)\t:%s\t:%s\n",
                errno, "Erreur ré-allocation dynamique",
                strerror(errno) );
            return EXIT_FAILURE;
        }
     
        p = pp;
        memset(p, 0x42, (sizeof(*p) * 20) );
        (void)fprintf(stderr, "%s\n", p );
     
     
        /*
        *   libération de le mémoire     
        */
        if( NULL != realloc(p, 0x0) ){
            (void)fprintf(stderr, "Erreur(%d)\t:%s\t:%s\n",
                errno, "Erreur libération mémoire",
                strerror(errno) );
            return EXIT_FAILURE;
        }
     
        (void)fprintf(stderr, ">%s<\n", p );   // /!\ Debug
        p = NULL;
     
        return EXIT_SUCCESS;
    }

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  10. #10
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Tu t'exprimes toujours dans le contexte restreint de la glibc là ? Parce qu'invoquer realloc avec une taille de zéro, c'est implementation defined.

  11. #11
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Tu t'exprimes toujours dans le contexte restreint de la glibc là ? Parce qu'invoquer realloc avec une taille de zéro, c'est implementation defined.
    Oui GlibC
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  12. #12
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 360
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 360
    Points : 20 378
    Points
    20 378
    Par défaut
    Un code possible de realloc par @dalfab:
    1 d'une part je ne comprends pas du tout l'intérêt de réecrire realloc

    2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     void *tmp = malloc( nouvelleTaille );
    qu'en est-il du cast bref du transtypage du bloc de mémoire alloué ?
    Si tu passes un tampon de int *, double* ou d'un typedef struct* comment le programme fait il pour convertir le type de données du tampon vers void* ?
    (C'est pour ça qu'on a crée les templates ( types génériques ) en C++ je ne sais pas si ça existe en C...)
    de toute façon la problématique c'est le transtypage

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Tu t'exprimes toujours dans le contexte restreint de la glibc là ? Parce qu'invoquer realloc avec une taille de zéro, c'est implementation defined.
    C'est difficile à comprendre par contre, car c'est disséminé sur diverses sections de l'annexe J de la norme en fait, ce n'était pas explicitement dit sur la doc de la fonction realloc(), mais en fait c'était expliqué quelques paragraphes plus haut:
    J'ai sous les yeux à la fois le n1256.pdf (C99 draft 3) et n1570.pdf (C11) qui tous deux disent ceci: (texte exact copié de n1570)
    • 7.22.3 Memory management functions
      If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.
    • J.1 Unspecified behavior
      The following are unspecified:
      • The amount of storage allocated by a successful call to the calloc, malloc, or
        realloc function when 0 bytes was requested (7.22.3).
    • J.2 Undefined behavior
      The behavior is undefined in the following circumstances:
      • A non-null pointer returned by a call to the calloc, malloc, or realloc function
        with a zero requested size is used to access an object (7.22.3).(En gros, le retour d'un malloc(0) ne doit pas être déréférencé)
    • J.3 Implementation-defined behavior
      A conforming implementation is required to document its choice of behavior in each of
      the areas listed in this subclause. The following are implementation-defined:
      J.3.2 Environment
      • Whether the calloc, malloc, and realloc functions return a null pointer or a
        pointer to an allocated object when the size requested is zero (7.22.3).


    Edit: Beurk: D'après la doc, Microsoft fait un truc hybride, où malloc(0) alloue un objet de taille nulle mais realloc(ptr, 0) fait un free(). Je présume que la raison pour cela est, comme d'habitude, la compatibilité avec les anciens programmes.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    C'est probablement parce que ça concerne toutes les fonctions d'allocation que c'est spécifié dans l'introduction de la section 7.22.3. Il convient d'ajouter à cet extrait le DR 400 : http://www.open-std.org/jtc1/sc22/wg...ary.htm#dr_400 .

    Add to subsection 7.31.12 a new paragraph (paragraph 2):

    Invoking realloc with a size argument equal to zero is an obsolescent feature.
    Un UB en devenir, donc ? Comme passer zéro à fgets..

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Autant pour POSIX ils peuvent plus ou moins se le permettre parce que Open Source etc., autant pour tenter de passer ça dans le standard C ils vont se faire des ennemis, car une fuite de mémoire n'est pas du tout quelque chose de facile à déboguer (quoique ça pourrait être contourné si le traitement pour une taille nulle est de retourner toujours le même buffer de taille zéro et ne jamais le libérer).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Points : 38
    Points
    38
    Par défaut
    Bonjour,

    Citation Envoyé par Mat.M Voir le message
    1 d'une part je ne comprends pas du tout l'intérêt de réecrire realloc
    J'en parle dans mon tout premier post de cette discussion et aussi ici :
    https://www.developpez.net/forums/d1...loc-ca-marche/

    Citation Envoyé par sambia39
    Exemple ci-dessous qui permet de voir que realloc peut être utilisé a la fois pour allouer redimensionnée ou libérer de la mémoire.
    Merci ! N'hésite pas à le poster sur ma proposition d'une faq : https://www.developpez.net/forums/d1...loc-ca-marche/


    J'aurai quelques questions pour bien comprendre :
    - Peut on rajouter des surcouche sur l'assembleur décidé par le constructeur, par exemple windows à sa manière de géré l'assembleur?

    - La libraire standard a été écrite de plusieurs façon : POSIX, glibc, microsoft... ?

    - Qu'elles sont les versions les plus importantes?

    Merci pour vos réponses

    PS: J'ai aussi changé le titre principal, qui avant était : "Allocation dynamique, les manques de la librairie standard". Ayant plus d'informations maintenant, je me rend compte que c'est bien plus complexe que cela est mon précédant titre est en fait abscons.

  17. #17
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Citation Envoyé par theludovyc Voir le message
    - Peut on rajouter des surcouche sur l'assembleur décidé par le constructeur, par exemple windows à sa manière de géré l'assembleur?
    Moi pas comprendre ce que tu as écrit , je ne vois pas ce que c'est une surcouche en assembleur , décidé par le constructeur ? (lequel intel ici ? surtout que le C n'est pas lié a un processeur particulier !) , Windows a sa manière de géré l'assembleur what ?
    Pour moi c'est du charabia ce que tu écrit
    Dans les détails principalement parce que l'assembleur n'est qu'une version lisible du binaire , secundo j'ai l'impression que tu confond le programme assembleur et le langage assembleur ! (mais pour le programme assembleur chaqu'un le code comme il veut , avec la syntaxe qu'il veut ).

    Néanmoins je trouve ce que tu dis un peu Hors sujet , il faut savoir que 99% de ce qu'on écrit en assembleur peut se faire en C :p

  18. #18
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Points : 38
    Points
    38
    Par défaut
    Bonjour @Kannagi,

    Ma question doit être vraiment stupide...

    Si je comprend bien ta façon de réponde un programme en assembleur, par exemple un "hello, world", je pourrai le compiler sous linux et l'exécuter sous windows sur une machine ayant le même processeur sans aucun soucis?

  19. #19
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 434
    Points : 43 065
    Points
    43 065
    Par défaut
    non, tu ne pourras pas l’exécuter sous Windows. Par ailleurs, ton programme va appeler des fonctions systèmes qui ne sont pas les même sous Linux et Windows. Par ailleurs la convention d'appel des fonctions est différente.

    Par contre, si tu écrit un code en C, en utilisant les fonctions de la libc (comme fopen, fread, fwrite), et en recompilant ton code, il fonctionnera sur Windows et Linux (avec un programme exécutable différent par plateforme).

    malloc existe sous Windows, fonctionnera pareil en externe (paramètres à fournir, paramètre retourné), mais pas pareil en interne. Tu as vu dans les posts que malloc sous Linux utilisait mmap et sbrk, ces fonctions n'existent pas sous Windows. Tout comme HeapAlloc, VirtualAlloc n’existe que sous Windows.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  20. #20
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Points : 38
    Points
    38
    Par défaut
    Ah ok j'ai tilt ! La bibliothèque standard est en faite une définitions de prototypes communs. Ensuite chaque os définis le code source. Du coup récupéré la taille d'une allocation dynamique vu que c'est pas prévu par la bibliothèque standard ça devient le dawa . D'où le conseil d'enregistrer sois même dans son programme les tailles. J'ai juste?

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/06/2016, 06h27
  2. Extraire les objets d'une librairie dynamique
    Par Lapk_gre dans le forum C
    Réponses: 13
    Dernier message: 29/07/2008, 14h49
  3. Question sur les problèmes d'allocation dynamique
    Par slylafone dans le forum C++
    Réponses: 23
    Dernier message: 25/10/2004, 14h18
  4. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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