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 :

Fonction retournant un pointeur


Sujet :

C

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 277
    Points : 230
    Points
    230
    Par défaut [résolu] Fonction retournant un pointeur
    Bonjour,

    jusqu'à présent, lorsque j'écrivais une fonction retournant un pointeur, je faisais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char *ma_fonction(...)
      char *result ;
     
      // traitement
      return result ;
    }
    Mais on m'a dit qu'il fallait déclarer le pointeur de retour en static :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char *ma_fonction(...)
      static char *result ;
     
      // traitement
      return result ;
    }
    Pourtant, j'avais jamais eu de problèmes avec ma façon de faire. Alors ?

  2. #2
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Mais on m'a dit qu'il fallait déclarer le pointeur de retour en static :
    Non, ce n'est pas nécessaire. La première formulation renvoie la valeur de result
    La déclaration static permet que la variable ne soit pas créée à chaque appel de la fonction et détruite en sortie de fonction mais possède la durée de vie du programme après sa création. result désigne alors toujours le même objet . on utilisera static si on veut que cette variable conserve sa valeur entre deux appels de la fonction.
    Tout cela n'est pas spécifique aux pointeurs
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  3. #3
    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
    Pour ce que tu retournes, à première vue, il n'y a aucun problème (je suppose que tu alloues le pointeur en question avec malloc())

    Le problème, c'est quand tu retournes l'adresse d'une variable locale: Là, la variable locale en question doit être déclarée en static, sinon elle est détruite quand la fonction retourne (et là, le pointeur retourné est donc invalide)

    À savoir aussi, losqu'on retourne l'adresse d'une variable statique, cela peut causer des problèmes en programmation multithread, car la variable est la même pour tous les threads
    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.

  4. #4
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Médinoc :
    Le problème, c'est quand tu retournes l'adresse d'une variable locale: Là, la variable locale en question doit être déclarée en static, sinon elle est détruite quand la fonction retourne (et là, le pointeur retourné est donc invalide)
    Tout à fait
    Ce qui signifie, pour la situation proposée par Le Furet, que dans ce cas ce n'est pas le pointeur qui doit être static mais la variable dont l'adresse est dans le pointeur
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: Fonction retournant un pointeur
    Citation Envoyé par Le Furet
    jusqu'à présent, lorsque j'écrivais une fonction retournant un pointeur, je faisais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char *ma_fonction(...)
      char *result ;
     
      // traitement
      return result ;
    }
    Correct si le pointeur a été correctement initialisé, notamment avec une adresse encore valide après exécution..
    Mais on m'a dit qu'il fallait déclarer le pointeur de retour en static :
    Soit tu a mal compris, soit 'on' est un ane.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char *ma_fonction(...)
      static char *result ;
     
      // traitement
      return result ;
    }
    Pourtant, j'avais jamais eu de problèmes avec ma façon de faire. Alors ?
    Alors l'important est que l'adresse retrournée soit valide après exécution de la fonction :
    Incorrect (adresse d'une variable non persistante, car locale)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    char *ver(void)
    {
       char s[] = "1.2";
       return s;
    }
    Correct (adresse d'une variable persistante, car static)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    char *ver(void)
    {
       static char s[] = "1.2";
       return s;
    }
    Correct (adresse d'une variable persistante, car alloué dynamiquement)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    char *ver_dyn(void)
    {
       char s[] = "1.2";
       char *p = malloc (strlen (s) + 1);
     
       if (p!=NULL)
       {
          strcpy (p, s);
       }
       return p;
    }
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 277
    Points : 230
    Points
    230
    Par défaut
    Merci de m'avoir répondu et fixé les idées sur ces cas-là.

    La portion de code qu'on m'a critiquée est celle-ci (c'est du GTK/GDK/Glib) :

    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
    35
    36
    GdkPixbuf *gdk_pixbuf_new_from_text ( gchar *text, GtkWidget *widget ) {
      GdkPixmap *temp_pixmap ;
      GdkPixbuf *temp_pixbuf = NULL ;
      PangoLayout *layout ;
      GdkGC *gc ;
      GdkColormap *cmap ;
      GdkColor *fg, *bg ;
      int sx, sy ;
     
      /* foreground and background colors */
      fg = gdk_color_new_from_RGB(255, 0, 0) ;
      bg = gdk_color_new_from_RGB(0, 0, 0) ;
     
      /* render layout to temp_pixmap */
      layout = gtk_widget_create_pango_layout(widget, text) ;
      pango_layout_get_pixel_size(layout, &sx, &sy) ;
      temp_pixmap = gdk_pixmap_new(NULL, sx, sy, 24) ;
      gc = gdk_gc_new(temp_pixmap) ;
     
      gdk_gc_set_foreground(gc, fg) ;
      gdk_gc_set_background(gc, bg) ;
      gdk_draw_layout( temp_pixmap, gc, 0, 0, layout) ;
     
      /* render temp_pixmap to temp_pixbuf */
      cmap = gdk_colormap_get_system() ;
      if (cmap==NULL) printf("cmap NULL\n") ;
      if (temp_pixmap==NULL) printf("temp_pixmap NULL\n") ;
      temp_pixbuf = gdk_pixbuf_get_from_drawable(NULL, temp_pixmap, cmap, 0, 0, 0, 0, sx, sy) ;
     
      /* free */
      g_object_free(layout) ;
      g_object_free(cmap) ;
      g_object_free(gc) ;
     
      return temp_pixbuf ;
    }
    On m'a conseillé de déclarer le temp_pixbuf en static, pour la raison que l'adresse de temp_pixbuf serait locale. Je suis prêt à le croire, mais comment aurais-je pu le deviner ?

  7. #7
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Bonjour,
    Citation Envoyé par Le Furet
    On m'a conseillé de déclarer le temp_pixbuf en static, pour la raison que l'adresse de temp_pixbuf serait locale. Je suis prêt à le croire, mais comment aurais-je pu le deviner ?
    Il n'y a aucun problème, l'adresse que tu retourne est donnée par Gtk et est valable tant que l'objet correspondant n'ai pas détruit (lors de la destruction du GdkPixmap associé)

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Le Furet
    La portion de code qu'on m'a critiquée est celle-ci (c'est du GTK/GDK/Glib) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    GdkPixbuf *gdk_pixbuf_new_from_text ( gchar *text, GtkWidget *widget ) {
      GdkPixbuf *temp_pixbuf = NULL ;
    <...> 
      temp_pixbuf = gdk_pixbuf_get_from_drawable(NULL, temp_pixmap, cmap, 0, 0, 0, 0, sx, sy) ;
    <...>
       return temp_pixbuf ;
    }
    On m'a conseillé de déclarer le temp_pixbuf en static, pour la raison que l'adresse de temp_pixbuf serait locale. Je suis prêt à le croire, mais comment aurais-je pu le deviner ?
    C'est confirmé, 'on' est un ane. Ton code est correct.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 277
    Points : 230
    Points
    230
    Par défaut
    Je vous remercie, je suis rassuré

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

Discussions similaires

  1. [POO]fonctions retournant un pointeur initialisé
    Par Invité dans le forum Débuter
    Réponses: 1
    Dernier message: 09/02/2011, 13h31
  2. Réponses: 4
    Dernier message: 30/04/2010, 11h33
  3. Réponses: 4
    Dernier message: 23/06/2009, 16h52
  4. Réponses: 6
    Dernier message: 04/03/2009, 19h50
  5. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37

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