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 :

Malloc dans une fonction


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 33
    Points : 18
    Points
    18
    Par défaut Malloc dans une fonction
    Salut !
    Je ne comprends pas pourquoi dans ce code, la fonction allouer ne fonctionne pas :
    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
    #include<stdio.h>
    #include<stdlib.h>
     
    void allouer(int* ptr){
      ptr = malloc(10*sizeof(int));
    }
     
    void ptrEstIlNull(int* ptr){
      if(ptr==NULL)
        printf("tab est null\n");
      else
        printf("tab n'est pas null\n");
    }
     
     
    int main(){
      int* tab;
      ptrEstIlNull(tab);
     
      allouer(tab);
      ptrEstIlNull(tab);
     
      tab = malloc(10*sizeof(int));
      ptrEstIlNull(tab);
     
      return 0;
    }
    Le résultat obtenu à la console est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tab est null
    tab est null
    tab n'est pas null
    Mais j'aurais imaginé que le résultat serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tab est null
    tab n'est pas null
    tab n'est pas null
    La solution, c'est de modifier la fonction allouer pour qu'elle renvoie le pointeur. Mais la solution je m'en moque, je veux juste comprendre.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    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 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Erreur de débutant ou

    Il faut passer un double pointeur, parce que sinon le pointeur retourné par malloc est mis dans la copie du pointeur (les joyeusetés du passage par copie )

    Sinon n'oublie pas le free

    Édit: Un petit schéma

    Pointeur simple: | tab |-> NULL / Passage de paramètre * / | ptr - copie de tab |-> X - retour de la fonction malloc.
    Double Pointeur: | tab |-> NULL / Passage de paramètre ** / | ptr | -> | tab |-> X - retour de la fonction malloc.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Ah d'accord. Je trouvais ça compliqué d'utiliser un double pointeur juste pour faire un simple malloc. C'est limite contre-intuitif.
    Déjà que les pointeurs, ça se comprend pas tout de suite, alors les double pointeurs...

    J'ai modifié le code et ça donne ça :
    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
    #include<stdio.h>
    #include<stdlib.h>
     
    void allouer(int** ptr){
      (*ptr) = malloc(10*sizeof(int));
    }
     
    void ptrEstIlNull(int* ptr){
      if(ptr==NULL)
        printf("tab est null\n");
      else
        printf("tab n'est pas null\n");
    }
     
     
    int main(){
      int* tab;
      ptrEstIlNull(tab);
     
      allouer(&tab);
      ptrEstIlNull(tab);
     
      tab = malloc(10*sizeof(int));
      ptrEstIlNull(tab);
     
      free(tab);
      return 0;
    }

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    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 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Il te manque un free à la ligne 22

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Oh tu m'embêtes, c'était juste pour l'exemple.

    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
    #include<stdio.h>
    #include<stdlib.h>
     
    void allouer(int** ptr){
      (*ptr) = malloc(10*sizeof(int));
    }
     
    void ptrEstIlNull(int* ptr){
      if(ptr==NULL)
        printf("tab est null\n");
      else
        printf("tab n'est pas null\n");
    }
     
     
    int main(){
      int* tab;
      ptrEstIlNull(tab);
     
      allouer(&tab);
      ptrEstIlNull(tab);
      free(tab);
     
      tab = malloc(10*sizeof(int));
      ptrEstIlNull(tab); 
      free(tab);
     
      return 0;
    }

  6. #6
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    C'est pour ton bien.

  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
    Bonjour
    Citation Envoyé par corent2 Voir le message
    Oh tu m'embêtes, c'était juste pour l'exemple.
    Ce qui a été dit est pour ton bien, mais si tu comptes ne pas utiliser les doubles pointeurs, tu peux toujours écrire une fonction qui te retourne un pointeur sur la zone qui a été allouer exemple
    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
     
    int *f_AllocPtr( size_t size ){
     
    	int *ptr = NULL;
    	size = ( size <= 0 ? 10 : size );
    	ptr = (int*)malloc( size *sizeof(int) );
    	if( ptr == NULL ){
    		fprintf(stderr, "Erreur d'allocation\n" );
    		exit( EXIT_FAILURE );
    	}
    	return( ptr );
    }
    int *f_Alloc2Ptr( size_t size ){
     
    	int *ptr = NULL;
    	size = ( size <= 0 ? 10 : size );
    	ptr = (int*)calloc( size, sizeof(int) );
    	if( ptr == NULL ){
    		fprintf(stderr, "Erreur Allocation\n" );
    		exit( EXIT_FAILURE );
    	}
    	return ( ptr );
    }
    à 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
    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 519
    Points
    41 519
    Par défaut
    Pourquoi caster le retour de malloc()? Tu n'as pas besoin de le faire.

    Si ça ne compile pas sans le cast, c'est que tu as fait une erreur ailleurs (oubli d'inclusion, compilation du code C par un compilateur C++, etc.)
    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.

  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
    Bonjour
    Désolé pour ma réponse tardive.
    Par habitude, je fais une conversion afin de convertir le pointeur retourné par ces deux fonctions (void*) dans le type de l'objet.
    à 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 é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 519
    Points
    41 519
    Par défaut
    En C, la conversion implicite suffit. Et la conversion explicite n'est plus recommandée par les inventeurs du langage depuis l'errata du nouveau testament K&R2.
    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.

  11. #11
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Bonjour,

    Je sais que tu vas dire qu'on est tatillon, mais :

    Citation Envoyé par corent2 Voir le message
    Le résultat obtenu à la console est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tab est null
    tab est null
    tab n'est pas null
    Mais j'aurais imaginé que le résultat serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tab est null
    tab n'est pas null
    tab n'est pas null
    Le résultat auquel tu aurais dû t'attendre est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tab n'est pas null
    tab n'est pas null
    tab n'est pas null
    En effet, lorsque tu écris int * tab;, tu déclares bien un pointeur "tab" sur un int, mais tu ne l'initialises pas, et il n'y a donc aucune raison qu'il vaille NULL plus qu'autre chose. A ce stade, ton pointeur vaut "quelque chose", et pointe sur une zone que tu n'as pas allouée, et donc dans laquelle tu n'as pas le droit d'écrire.

    Si je reprends ton code :

    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
    #include<stdio.h>
    #include<stdlib.h>
     
    void allouer(int** ptr){
      (*ptr) = malloc(10*sizeof(int));
    }
     
    void ptrEstIlNull(int* ptr){
      if(ptr==NULL)
        printf("tab est null\n");
      else
        printf("tab n'est pas null\n");
    }
     
     
    int main(){
      int* tab;
    
    /* Initialisations */
    tab = NULL;
    
      ptrEstIlNull(tab);
     
      allouer(&tab); /* Tu ne traites pas le cas où l'allocation échoue, ce qui peut faire crasher ton programme */
      ptrEstIlNull(tab);
      free(tab); /* Non symétrique : tu as une fonction pour allouer, mais pas pour désallouer, ce qui n'est pas une bonne habitude */
     
      tab = malloc(10*sizeof(int));
      ptrEstIlNull(tab); 
      free(tab);
     
      return 0;
    }
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

Discussions similaires

  1. Recuperation de formulaire dans une fonction
    Par arsgunner dans le forum ASP
    Réponses: 5
    Dernier message: 23/06/2004, 15h04
  2. Transmission d'un objet crée dans une fonction
    Par EvilAngel dans le forum ASP
    Réponses: 2
    Dernier message: 10/05/2004, 20h19
  3. Utilisez MinimizeName() dans une fonction
    Par James_ dans le forum C++Builder
    Réponses: 7
    Dernier message: 07/05/2004, 18h05
  4. [Postgresql]Connecter à une autre base dans une fonction
    Par alex2205 dans le forum Requêtes
    Réponses: 2
    Dernier message: 05/05/2003, 11h30
  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, 20h14

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