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 :

question sur malloc


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 4
    Par défaut question sur malloc
    si je fais un malloc ds une fonction, et que je "return" le pointeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char * mafonction(){
             char * ptr;
     
             ptr = malloc ( x * sizeof(char));   // x car peu importe le nb
     
             (...)
              return ptr;
    }
    ensuite un appel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char * ptr2;
     
    ptr2 = mafonction();
    En terme de mémoire, le pointeur ptr est detruit ?
    Ds ce cas j'ai juste a faire free(ptr2) pour tout libérer ?

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par MegaNono
    si je fais un malloc ds une fonction, et que je "return" le pointeur :
    Ce que tu retournes est une valeur. Ici, cette valeur est une adresse. C'est l'adresse du bloc alloué.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char * mafonction(){
             char * ptr;
     
             ptr = malloc ( x * sizeof(char));   // x car peu importe le nb
     
             (...)
              return ptr;
    }
    ensuite un appel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char * ptr2;
     
    ptr2 = mafonction();
    En terme de mémoire, le pointeur ptr est detruit ?
    Oui, comme toute variable automatique...
    Ds ce cas j'ai juste a faire free(ptr2) pour tout libérer ?
    Oui.

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 4
    Par défaut
    merci

  4. #4
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Penses au résolu qui se trouve dans le menu "Outils de la discussion" en haut à droite...

    Jc

  5. #5
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Je croyais qu'il était impossible de construire des tableaux dans des fonctions et les récupérer de quelque manière que ce soit.

    Donc ceci est seulement vrai pour les tableaux statiques?
    Et donc on peut allouer un tableau dans une fonction et le récupérer et manipuler sans problème en dehors de la fonction?

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    Je croyais qu'il était impossible de construire des tableaux dans des fonctions et les récupérer de quelque manière que ce soit.

    Donc ceci est seulement vrai pour les tableaux statiques?
    Et donc on peut allouer un tableau dans une fonction et le récupérer et manipuler sans problème en dehors de la fonction?
    Le principe général c'est que l'adresse retournée doit être valide. Point. Tu appliques ensuite ce principe au cas par cas.

    D'autre part, on ne sait pas passer/retourner de tableau, mais seulement l'adresse du premier élément de celui-ci (ou l'adresse du tableau, mais c'est plus rare et pas très pratique...)

  7. #7
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int* f(){
             int t1[]={1,2,3};
             return t1;
             }
     
    ...
     
    int *t2=f();
    printf("%d",t2[2]);
    fonctionne en effet alors que j'ai "toujours" vu: t2 sera invalide.

    Est-ce risqué de faire cela par rapport à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void f(int *t){
             t[0]=1;
             t[1]=2;
             t[2]=3;
             return;
             }
    ?

  8. #8
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par seriousme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int* f(){
             int t1[]={1,2,3};
             return t1;
             }
     
    ...
     
    int *t2=f();
    printf("%d",t2[2]);
    fonctionne en effet alors que j'ai "toujours" vu: t2 sera invalide.
    [/code] ?
    Cela fonctionne parceque tu explotes t2 aussitot après le retour de ta fonction. La pile n'est pas altérée.

    Mais si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int* f(){
              int t1[]={1,2,3};
              return t1;
    }
     
     ...
     
    int *t2=f();
    autreFonction();
    printf("%d",t2[2]);
    Il y a de forte chance que ton pointeur t2 ne soit plus valide.

  9. #9
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int* f(){
             int t1[]={1,2,3};
             return t1;
             }
    ...
    int *t2=f();
    printf("%d",t2[2]);
    fonctionne en effet alors que j'ai "toujours" vu: t2 sera invalide.
    Non, le code est erroné pour les raisons exposées par Emmanuel : L'adresse retournée cesse d'être valide puisque t1 est détruit en sortie de fonction. Si ca semble marcher, c'est pur hasard et mauvaise chance.
    Si on veut créer le tableau dans la fonction et qu'il survive à la sortie, il faut le faire par allocation dynamique
    Est-ce risqué de faire cela par rapport à:
    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f(int *t){ t[0]=1;
     t[1]=2;
     t[2]=3;
     return; }
    Ceci est peut être juste : il faut que l'argument t corresponde à un tableau de 3 éléments au moins.

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    fonctionne en effet alors que j'ai "toujours" vu: t2 sera invalide.
    T'as rien compris à ce que j'ai dit. L'adresse retournée doit être valide.
    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
     
    #include <stdio.h>
    static int* f(void)
    {
       int t1[] =
          {
             1, 2, 3
          };
       return t1;
    }
     
    int main (void)
    {
       int *t2 = f();
       printf("%d", t2[2]);
       return 0;
    }
    Or, à l'évidence, elle ne l'est pas. Un compilateur bien reglé s'en rend compte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Compiling: main.c
    main.c: In function `f':
    main.c:8: warning: function returns address of local variable
    Linking console executable: C:\dev\forums\OP\01.exe
    Process terminated with status 0 (0 minutes, 0 seconds)
    0 errors, 1 warnings

  11. #11
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par crocodilex
    Cela fonctionne parceque
    Non. Ca ne fonctionne pas du tout. Le comportement est indéfini. Point.

  12. #12
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    T'as rien compris à ce que j'ai dit.
    En effet.

    1)Alors à quoi peut servir de renvoyer l'adresse du premier élément si ce n'est pas valide?
    2)Par contre est-ce que ç'est valide si t est alloué dynamiquement?

  13. #13
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Non. Ca ne fonctionne pas du tout. Le comportement est indéfini. Point.
    Nous savons tous que le comportement est indéfini. J'essayais juste de lui donner une explication (ce n'est peut etre pas la meilleure), à savoir pourquoi dans son exemple, cela pouvait marcher. C'est tout.

  14. #14
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par seriousme
    1)Alors à quoi peut servir de renvoyer l'adresse du premier élément si ce n'est pas valide?
    Ce n'est pas parce que c'est techniquement possible que c'est valide. Le C est plein d'exemples comme ça.
    • lire une variable non initialisée
    • déréférencer un pointeur non initialisé
    • ecrire au-dela des limites d'un tableau
    • etc.
    2)Par contre est-ce que ç'est valide si t est alloué dynamiquement?
    Déjà répondu.

  15. #15
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par crocodilex
    Nous savons tous que le comportement est indéfini. J'essayais juste de lui donner une explication (ce n'est peut etre pas la meilleure), à savoir pourquoi dans son exemple, cela pouvait marcher. C'est tout.
    Perte de temps. On ne peut pas définir ce qui est indéfini. Ca parait logique, non ?

  16. #16
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Déjà répondu.
    Donc oui, c'est valable.

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

Discussions similaires

  1. question sur malloc (je dois le recoder)
    Par lludol dans le forum C
    Réponses: 10
    Dernier message: 31/01/2014, 09h00
  2. question sur malloc
    Par Elstak dans le forum C
    Réponses: 6
    Dernier message: 10/05/2007, 19h21
  3. une question sur malloc()
    Par marocleverness dans le forum C
    Réponses: 5
    Dernier message: 02/05/2006, 20h26
  4. Question sur malloc
    Par mikedavem dans le forum C
    Réponses: 4
    Dernier message: 14/04/2006, 08h22
  5. Encore une question sur malloc
    Par IG88 dans le forum C
    Réponses: 5
    Dernier message: 23/06/2004, 15h35

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