Partage
  • Partager sur Facebook
  • Partager sur Twitter

malloc

plusiuer forme de malloc

Sujet résolu
    8 avril 2021 à 14:18:40

    Bonjour,

    ----------------------------------------------------------------------------------------------------------------------------------

    Je pense que je ne suis pas seul à voir des incomprehensions sur le  malloc  (je suis débutant, je le précise).

    Dans mon apprentissage en C, le malloc je l'ai vu de cette façon , qui est facile à premier à bord :

    malloc(sizeof(type de donné)) type donné : int, long, float , double ....
    Exemple malloc(1*sizeof(int))

    Qui signifie réserve moi en mémoire une case de 4 octet (int et selon le syteme 32 ou 64bytes).

    la je tiens la barre.

    ----------------------------------------------------------------------------------------------------------------------------------

    Mais par la suite ou j'ai commencer à voir le malloc d'un toute autre air, c'est quand c'etait pour construire une matrice 2-D en dynamique :

    int **p; 
    p = malloc(sizeof(int *));

     Qui signifie réserve moi en mémoire une case qui va contenir un pointeur qui pointera sur de type int.

    La c'etait bon.

    ----------------------------------------------------------------------------------------------------------------------------------

    Mais ou j'ai commencer à decrocher sur malloc, c'est quand j'ai commencé à étudié les liste chainé.

    Voici un exemple d'un malloc qui ma semblé compliqué :

    Liste *liste = malloc(sizeof(*liste));

     Liste une structure :

    typedef struct Liste Liste;
    struct Liste
    {
    	Element *premier;
    };

    Le malloc qui signifie : réserve moi en mémoire une case de type ??????????????????, je ne sais pas l'expliqué

    Explication de OC:

    " L'ordinateur saura qu'il doit allouer l'espace nécessaire au stockage de la structure Liste. 
    " OC

    "On aurait aussi pu écrire sizeof(Liste), mais si plus tard on décide de modifier le type du pointeur liste, on devra aussi adapter le sizeof." OC

    -----------------------------------------

    Mais quelle est le typage de Liste : struc. Comment ça "struct" est un type?

    Les type que j'ai vu c'est int, double, int *, int**

    mais STRUCT j'arrive pas à saisir la nuance de ce type.

    ----------------------------------------------------------------------------------------------------------------------------------

    Et encore un autre malloc que je comprend pas qui va dans le sens du dernier:

    Liste *liste = (Liste*)(malloc(sizeof(liste)).

    La c'est comme-ci tu m'as mis devant mike tyson à l'age de c'est 18 ans .

    donc pour résumé voici les deux malloc que je ne comprends rien:

    Liste *liste = (Liste*)(malloc(sizeof(Liste)).
    Liste *liste = malloc(sizeof(*liste));

    MErci de l'aide

    • Partager sur Facebook
    • Partager sur Twitter
      8 avril 2021 à 14:40:40

      Bonjour,

      ton problème c'est pas forcément la fonction malloc, c'est plutôt l'opérateur sizeof.

      La fonction malloc est hyper simple : un seul paramètre, la taille en char (=byte=octet pour simplifier) d'une zone mémoire qu'on voudrait avoir, et un seul retour un pointeur qui pointe soit nulle part (NULL) pour indiquer qu'il y a eu une erreur soit qui n'est pas NULL et pointe vers un endroit valide de la mémoire où tu pourras accéder à la taille indiquée bytes.

      Ça tu l'as bien compris.

      Passons maintenant à sizeof. Cet opérateur renvoie la taille de ce qu'on lui donne en paramètre. Par exemple avec le code :

      #include <stdio.h>
      
      int main(void)
      {
      	short i=42;
      	short *p=&i;
      
      	printf("sizeof(short) = %zu\n", sizeof(short));
      	printf("sizeof(i)     = %zu\n", sizeof(i));
      	printf("sizeof(p)     = %zu\n", sizeof(p));
      	printf("sizeof(*p)    = %zu\n", sizeof(*p));
      
      	return 0;
      }
      

      On obtient en sortie :

      sizeof(short) = 2
      sizeof(i)     = 2
      sizeof(p)     = 8
      sizeof(*p)    = 2
      

      et tu vois que si tu donnes à sizeof directement le type short ou une variable de type short ou une variable de type pointeur sur short que tu déréférences en opérande alors le résultat est le même.

      Dans le cas :

      Liste *liste = malloc(sizeof(*liste));

      sizeof prend ici comme opérande *liste, tu déréférences (en gros hein …) la variable liste qui est de type pointeur sur Liste et tu tombes donc sur un objet de type Liste dont tu prends la taille. C'est donc strictement équivalent à :

      Liste *liste = malloc(sizeof(Liste));

      d'une manière générale une ligne comme :

      T *new=malloc( sizeof( *new ) );

      sera toujours correcte car tu demandes d'allouer la mémoire qu'il faut pour stocker ce vers quoi pointera ta variable, quel que soit le type T. Le jour où tu refactores ton code, si T change tu n'as à le modifier qu'une fois au lieu de deux dans :

      T *new=malloc( sizeof(T) );

      IbBk a écrit:

      ----------------------------------------------------------------------------------------------------------------------------------

      Et encore un autre malloc que je comprend pas qui va dans le sens du dernier:

      Liste *liste = (Liste*)(malloc(sizeof(liste)).

      La c'est comme-ci tu m'as mis devant mike tyson à l'age de c'est 18 ans .

      donc pour résumé voici les deux malloc que je ne comprends rien:

      Liste *liste = (Liste*)(malloc(sizeof(Liste)).
      Liste *liste = malloc(sizeof(*liste));

      MErci de l'aide

      Attention à la casse !!! Liste ≠ liste …

      le (Liste *) devant le malloc s'appelle un cast ou transtypage. C'est considéré comme une (hyper) mauvaise pratique que d'utiliser ça. Si ton compilo te pose des problèmes avec ça … alors c'est que tu compiles en C++ et non en C.

      • Partager sur Facebook
      • Partager sur Twitter
        8 avril 2021 à 14:49:09

        Bonjour,

        En effet pour comprendre tes 2 malloc() il faut voir à quoi correspond un élément de liste. Ce qu'il faut allouer c'est :
        - une zone qui contiendra le début de la liste, problème ce début est nommé avec le type 'Liste' dans ton exemple.
        - ensuite les éléments chaînés doivent avoir une forme :

        struct Element
        {
           ... ... ... les données de l'élement
           struct Element*  suivant;
        };

        C'est cet élément le plus important et tu ne l'a pas indiqué.
        Ensuite il faut allouer 2 choses l'entête de liste et chacun des éléments. Et donc la ligne

        Liste *liste = malloc(sizeof(*liste));  // ici *liste est un objet

        est bien correcte, on alloue une structure Liste et on va pointer dessus. *liste désigne ce qui est pointé par liste, on aurait pu écrire:

        Liste *liste = malloc(sizeof(Liste));   // ici Liste est un type de donnée

        personnellement, je préfère la première notation.

        L'autre malloc() par contre est forcément une erreur:

        Liste *liste = (Liste*)(malloc(sizeof(liste))

        On alloue un objet de la taille de liste et on dit que liste pointe dessus. On alloue donc un pointeur alors qu'il faut à un moment allouer une zone pour mettre les objets de type Element. Mais coup de bol, *liste contient juste un pointeur et liste est un pointeur donc les 2 ont la même taille, mais cette ligne est fausse.
        Je pense que la ligne qui alloue un maillon est ailleurs dans le code, ça devrait ressembler à :

        Element *element = malloc(sizeof(*element));



        • Partager sur Facebook
        • Partager sur Twitter

        En recherche d'emploi.

          8 avril 2021 à 15:23:06

          T *new=malloc( sizeof( *new ) );

          sera toujours correcte car tu demandes d'allouer la mémoire qu'il faut pour stocker ce vers quoi pointera ta variable, quel que soit le type T. Le jour où tu refactores ton code, si T change tu n'as à le modifier qu'une fois au lieu de deux dans :

          T *new=malloc( sizeof(T) );

          White.

           _______________________________________________________________

          Moi:

           Tu peux avoir le même raisonnement  avec :

          T *new=malloc( sizeof( *new )

           Si à l'avenir tu change new, tu vas le changer deux fois.

          Quel ferais la raison qu'il est plus probable de changer T que new ?

          -
          Edité par IbBk 8 avril 2021 à 15:24:07

          • Partager sur Facebook
          • Partager sur Twitter
            8 avril 2021 à 16:54:19

            C'est pas faux. Mais il t'arrivera plus souvent de changer de type que le nom d'une variable locale, enfin je te dis ça par expérience. Cette dernière écriture est aussi moins sujette aux erreurs et te permet de ne pas avoir à trop réfléchir. Par exemple dans un bout de code tu va écrire :

            T *new=NULL;
            
            bla bla bla ...
            
            beaucoup plus bas ...
            
            
            new = malloc( <ah mince c'est quoi encore le type de new ???

            Alors que lorsque tu écris :

            new = malloc( sizeof *new );

            bah c'est forcément bon et tu n'as pas à remonter pour vérifier le type, ou avoir à débuger par la suite car tu t'es trompé de type etc …


            • Partager sur Facebook
            • Partager sur Twitter
              8 avril 2021 à 17:06:01

              Je comprends. il est plus problablr (d’après ton expérience) de  changer de nom type de la strucutre que de nom de variable au sein de la structure.

              Parfait. C'est noté.

              • Partager sur Facebook
              • Partager sur Twitter

              malloc

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown