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 :

Comment realloc devine la taille du bloc mémoire d'origine?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti

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

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Par défaut Comment realloc devine la taille du bloc mémoire d'origine?
    Bonjour,

    Comme vous avez pu le lire dans le titre une question me turlupine sur la fonction realloc !!!

    Vous pouvez voir dans ce post https://www.developpez.net/forums/d1...loc-ca-marche/ que je propose une interprétation de la fonction realloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void *realloc(void *blocACopier, size_t nouvelleTaille){
      void *tmp=malloc(nouvelleTaille); //allocation d'une nouvelle zone mémoire
      if(tmp==NULL){ //allocation raté
        return NULL;
      }
      memcopy(tmp, blocACopier, ancienneTaille); //copie
      free(blocACopier); //libération
      return tmp;
    }
    On peut y voir que ancienneTaille ne fait pas parti des paramètres et est déterminée par la fonction elle même. Or après plusieurs recherche obtenir la taille d'une zone mémoire allouée dynamiquement avec la bibliothèque standard est impossible, seulement realloc y arrive très bien !

    D'où ma question : comment elle fait?

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

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

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    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
    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;
    }

  3. #3
    Membre averti

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

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Par défaut
    Bonjour @dalfab,

    Merci pour ta réponse. C'est dommage que ça ne soit pas standardisé, pourquoi un tel choix a t'il été fait?

  4. #4
    Membre très actif
    Homme Profil pro
    Programmeur des cavernes
    Inscrit en
    Août 2017
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Programmeur des cavernes
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2017
    Messages : 364
    Par défaut
    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.

  5. #5
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 539
    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 539
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcopy(tmp, blocACopier, ancienneTaille);
    si ancienneTaille est supérieure à nouvelleTaille bonjour les plantages et dépassement mémoire !

  6. #6
    Membre averti

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

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Par défaut
    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.
    Bonjour @Jamatronic,
    Je ne vois pas l'intérêt d'interdire cela au programmeur. Le faire d'accord, où est ce que je peut trouvé des tutos précis là dessus?

    Citation Envoyé par Mat.M Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcopy(tmp, blocACopier, ancienneTaille);
    si ancienneTaille est supérieure à nouvelleTaille bonjour les plantages et dépassement mémoire !
    Bonjour @Mat.M
    J'ai mis un lien vers mon post ou j'explique que je fait cette interprétation qu'en cas d'une augmentation.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    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.
    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).
    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.

  8. #8
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Choix délibéré ou oubli, je l'ignore.
    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.


    @dalfab : même si ce que tu écris était vérifié dans 85% des cas ça reste de la pure spéculation. La libc fait ce qu'elle veut en fin de compte.

  9. #9
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 281
    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 : 18 281
    Par défaut
    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
    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

  10. #10
    Membre averti

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

    Informations forums :
    Inscription : Juillet 2013
    Messages : 39
    Par défaut
    Merci pour vos réponses c'est hyper enrichissant !

    On s'éloigne un peu du sujet alors j'ai ouvert une nouvelle discussion https://www.developpez.net/forums/d1...irie-standard/

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/01/2014, 15h39
  2. Comment connaître la taille de la mémoire ?
    Par mmaximum dans le forum Programmation d'OS
    Réponses: 8
    Dernier message: 08/01/2009, 18h09
  3. Réponses: 2
    Dernier message: 19/02/2007, 15h46
  4. Réponses: 5
    Dernier message: 15/04/2004, 13h24
  5. Partage de blocs mémoire entre 2 processus
    Par rolkA dans le forum Windows
    Réponses: 6
    Dernier message: 18/11/2003, 19h08

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