1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    juillet 2013
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2013
    Messages : 34
    Points : 22
    Points
    22

    Par défaut [FAQ] Realloc comment ça marche?

    Bonjours,

    J'ai fait quelques recherche sur la fonction realloc pour savoir comment l'utiliser dans mon programme en passant notamment par :
    https://fr.wikibooks.org/wiki/Progra...a_m%C3%A9moire
    http://rperrot.developpez.com/articles/c/allocationC/
    https://www.gladir.com/CODER/C/realloc.htm

    Ils donnent plusieurs définitions ou explications similaire :
    realloc tentera de réajuster la taille du bloc pointé par ancien_bloc à la nouvelle taille spécifiée
    a fonction realloc() tente de redimensionner un bloc mémoire
    Cette fonction permet de changer la taille d'un bloc de mémoire dynamique
    "Nous passons donc comme premier argment tableau, qui est le pointeur que l'on va redimenssioner"

    De cette ambiguïté l'ont peut penser de la façon suivante :
    Realloc tente de redimensionner le bloc pointer par le premier argument en regardant s'il y a de la place en mémoire à sa suite, si oui il est agrandi, sinon cela ne marche pas.

    J'espère que cela pourra en aider plus d'un à y voir plus clair !

    Je propose donc de rajouter dans la FAQ C en 4.5 :
    Realloc comment ça marche?
    Lors d'une pratique de l'allocation mémoire, parfois l'envie d'augmenter ou de diminué la taille d'une allocation se fait sentir. La fonction realloc est utile principalement dans ces deux cas.

    prototype de la fonction realloc :
    void *realloc(void *blocACopier, size_t nouvelleTaille);

    Le plus couramment : pour une augmentation, la fonction realloc va chercher en mémoire la taille demandé en second argument et y recopier le contenu pointer par le premier argument puis le libère automatiquement. Si elle échoue à n'en pas trouvé, NULL est retourné et elle ne libère pas le contenu pointer par le premier argument. Il est à savoir que la fonction realloc ne peut échouer que dans le cas d'une augmentation.
    La fonction realloc peut alors s'interpréter (le code suivant n'est pas compilable) de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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;
    }
    Dans le cas d'une augmentation comme la fonction realloc peut échoué, il est recommandé de l'utilisé de la façon suivante (le code suivant peut être compilé et exécuté):
    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
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(){
      char *a=(char*)malloc(sizeof(char)*8); //première allocation
     
      printf("%p : adresse de a alloc\n", a);
     
      void *tmp=realloc(a, sizeof(char)*16); //on désire un bloc 2 fois plus grand
      if(tmp==NULL){
        printf("Echec de la reallocation mémoire\n");
        exit(1);
      }
     
      printf("Réussite de la reallocation mémoire !\n");
     
      a=(char*)tmp;
     
      printf("%p : adresse de a realloc\n", a);
     
      return 0;
    }
    Pour une diminution, la fonction realloc peut agir sois comme précédemment, sans échec possible, et allouer une nouvelle zone mémoire, recopier, et retourner un pointeur différent. Sois simplement diminuer la taille du bloc alloué et retourner un pointeur égal au premier argument.

    Pour finir, la fonction realloc peut être utilisée de la même façon que la fonction malloc en mettant le premier argument a NULL.

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 607
    Points : 3 085
    Points
    3 085

    Par défaut

    Bonjour,

    Il y a aussi le cas où la taille demandée est plus petite que la taille courante à prendre en compte.

    realloc() peut ou pas conserver la valeur initiale du pointeur. S'il retourne un autre pointeur c'est qu'il a copié les données précédentes dans le nouveau buffer et libéré le buffer précédent. realloc() ne peut échouer que dans le cas où on souhaite agrandir la taille du buffer, il retourne alors NULL (et ne libère pas le buffer précédent).

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    juillet 2013
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2013
    Messages : 34
    Points : 22
    Points
    22

    Par défaut

    Citation Envoyé par dalfab Voir le message
    Bonjour,

    Il y a aussi le cas ...
    Premier post mis à jour dit moi ce que tu en pense !

  4. #4
    Expert éminent sénior

    Profil pro
    Développeur informatique
    Inscrit en
    novembre 2006
    Messages
    6 385
    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 : 6 385
    Points : 12 710
    Points
    12 710

    Par défaut

    Citation Envoyé par theludovyc Voir le message
    De cette ambiguïté l'ont peut penser de la façon suivante :
    dans un langage informatique l'ambiguïté ça n'existe pas sinon ça ne compile pas...
    quand on définit quelque chose dans un code source c'est clair et net.

    Ensuite Realloc ne tente rien du tout , realloc fait ce que l'on lui dit de faire....
    realloc n'échoue que s'il ne peut pas réallouer un bloc mémoire dans le tas ( en anglais c'est heap memory ) c.a.d. s'il n'y a pas assez de mémoire vive.
    La mémoire dans le tas c'est l'OS qui l'alloue par rapport à la mémoire statique bref les cases mémoires où sont rangées les variables du programme exécutable.

    Donc j'ai l'impression que l'utilisation de malloc et realloc n'est pas du tout comprise.
    Dans un langage "managé" comme Java ou C# c'est pareil.

    comme je l'ai écris dans un autre fil de discussion , ancienneTaille doit être inférieure à nouvelleTaille sinon il y a risque de fuite mémoire notamment sur l'appel de memcpy
    Sinon c'est vouloir écraser un tampon mémoire trop petit par rapport à ce que l'on veut copier..
    Ensuite on ne sait pas d'où vient ancienneTaille
    Citation Envoyé par theludovyc Voir le message
    Realloc tente de redimensionner le bloc pointer par le premier argument en regardant s'il y a de la place en mémoire à sa suite, si oui il est agrandi, sinon cela ne marche pas.
    realloc ne regarde pas forcément s'il y a de la mémoire à sa suite ;
    realloc regarde s'il y a des zones mémoires disponibles ; en général les systèmes d'exploitation le font de manière paginée ( consulter pour cela le livre de Jeffrey Richter concernant Windows)

    Ensuite je pense que l'utilisation de malloc et realloc n'est pas du tout comprise

    Si je veux allouer un tableau dynamique , j'appelle malloc qui va m'allouer le nombre d'éléments par la taille de type de cet élément ( par exemple un int en général c'est 4 octets)
    et malloc va retourner une adresse mémoire.

    En Assembleur c'est une adresse où les registres ( avec intel par exemple EAX,ECX...) vont éventuellement chercher les données.
    Donc mettons que l'on ait une adresse sur 32 bits, à cette adresse sera le descripteur/pointeur d'un bloc contigü.
    Pour adresser ce bloc le descripteur va se décaler de sizeof( type de donnée ).

    Pour ce qui est de realloc à mon sens le programme va effacer le pointeur alloué par malloc et en réattribuer un nouveau en faisant effectivement une sorte de memcpy.

    Sauf que lors de la compilation en code machine donc en code assembleur ( puisque la compilation du langage C donne du code assembleur ), le compilateur lui il le sait que tel tableau alloué dynamiquement en mémoire est géré par tel pointeur/descripteur ; la gestion se fait par décalage pointeur.
    Pour ce qui de la valeur du pointeur c'est l'OS qui attribue cette valeur en fonction des disponibilités mémoires
    Ne dites pas : "chercher la petite bête" mais plutôt "effectuer un travail d'entomologiste."
    Pour corriger des bugs c'est pareil

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    juillet 2013
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2013
    Messages : 34
    Points : 22
    Points
    22

    Par défaut

    Citation Envoyé par Mat.M Voir le message
    dans un langage informatique l'ambiguïté ça n'existe pas sinon ça ne compile pas...
    quand on définit quelque chose dans un code source c'est clair et net.
    Bonjour @Mat.M,
    L'ambiguïté ne désigne pas le code source, j'ai employé ce terme pour désigné les définitions que j'ai trouvé.

    Citation Envoyé par Mat.M Voir le message
    Ensuite Realloc ne tente rien du tout , realloc fait ce que l'on lui dit de faire....
    realloc n'échoue que s'il ne peut pas réallouer un bloc mémoire dans le tas ( en anglais c'est heap memory ) c.a.d. s'il n'y a pas assez de mémoire vive.
    Je vois ce que tu veux dire. Tu aurais surement préféré quelque chose du genre : realloc est une fonction pour réalloué un bloc mémoire, elle peut échoué s'il n'y a pas assez de place en mémoire vive. Cependant avec tenter on sait qu'il peut y avoir une erreur, un echec. Ainsi : realloc est une fonction qui tente de réalloué un bloc mémoire, elle échoue s'il n'y a pas assez de place en mémoire vive. Je trouve la seconde version beaucoup plus parlante.

    Citation Envoyé par Mat.M Voir le message
    Donc j'ai l'impression que l'utilisation de malloc et realloc n'est pas du tout comprise.
    Dans un langage "managé" comme Java ou C# c'est pareil.
    C'est a dire?

    Citation Envoyé par Mat.M Voir le message
    comme je l'ai écris dans un autre fil de discussion , ancienneTaille doit être inférieure à nouvelleTaille sinon il y a risque de fuite mémoire notamment sur l'appel de memcpy
    Sinon c'est vouloir écraser un tampon mémoire trop petit par rapport à ce que l'on veut copier..
    Ensuite on ne sait pas d'où vient ancienneTaille
    Oui c'est pour cela que je ne fait cette interprétation qu'en cas d'une augmentation. Je vais faire une mise a jour pour parlé de ancienneTaille, c'est vrai qu'elle est là un peu par magie pour le coup ^^.

    Citation Envoyé par Mat.M Voir le message
    realloc ne regarde pas forcément s'il y a de la mémoire à sa suite ;
    realloc regarde s'il y a des zones mémoires disponibles ; en général les systèmes d'exploitation le font de manière paginée ( consulter pour cela le livre de Jeffrey Richter concernant Windows)
    Donc si l'on obtient le même pointeur c'est part chance? Merci pour le livre c'est ce que je cherchais. Par contre t'a pas moins cher?

    Citation Envoyé par Mat.M Voir le message
    En Assembleur c'est une adresse où les registres ( avec intel par exemple EAX,ECX...) vont éventuellement chercher les données.
    Donc mettons que l'on ait une adresse sur 32 bits, à cette adresse sera le descripteur/pointeur d'un bloc contigü.
    Pour adresser ce bloc le descripteur va se décaler de sizeof( type de donnée ).
    Tu peut m'en dire plus? C'est à dire décaler de sizeof? Je n'arrive pas à comprendre.

    Citation Envoyé par Mat.M Voir le message
    Sauf que lors de la compilation en code machine donc en code assembleur ( puisque la compilation du langage C donne du code assembleur ), le compilateur lui il le sait que tel tableau alloué dynamiquement en mémoire est géré par tel pointeur/descripteur ; la gestion se fait par décalage pointeur.
    Donc il n'y a pas de sorte de memcopy?

    Citation Envoyé par Mat.M Voir le message
    Pour ce qui de la valeur du pointeur c'est l'OS qui attribue cette valeur en fonction des disponibilités mémoires
    Est ce qu'il y a d'autre fonctions que malloc, calloc, free, realloc... Pour jouer avec de façon plus précise, plus directe?

    Merci pour tes réponses

Discussions similaires

  1. ToAsciiEx, comment cela marche ?
    Par mikyfpc dans le forum C++Builder
    Réponses: 2
    Dernier message: 17/02/2004, 22h39
  2. [MFC] list box : comment ça marche
    Par runn2 dans le forum MFC
    Réponses: 4
    Dernier message: 28/01/2004, 13h36
  3. [SYNEDIT] -> Comment ça marche ?
    Par MaTHieU_ dans le forum C++Builder
    Réponses: 2
    Dernier message: 18/01/2004, 20h11
  4. [TP][Turbo Vision] comment ça marche ??
    Par Costello dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 05/08/2003, 01h24
  5. [update][req. imbriquee] Comment ca marche ??
    Par terziann dans le forum Langage SQL
    Réponses: 3
    Dernier message: 11/07/2003, 13h51

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