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 :

Exercice structure et pointeur


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 19
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Exercice structure et pointeur
    Bonjour,

    Voici un exercice que je du effectué, et je voulais avoir votre avis dessus. On m'a demandé de modifier un bout de programme pour que celui-ci fonctionne correctement.

    Voici le programme:
    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
    typedef struct{
     
    int hauteur, largeur;
    unsigned char* pixels;
    }image_t;
     
     
    void alloue_image(image_t* i, int h, int l)
    {
    i.hauteur=h;
    i.largeur=h;
    i.pixels=malloc(h*l+1);
    }
     
    return i;
     
    }
    Voici ce que j'ai écrit:
    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
     
     
     
     
    typedef struct image_t image_t;
    struct image_t
    {
    int hauteur;
    int  largeur;
    unsigned char* pixels;
     
    };
     
    void alloue_image(image_t* i, int h, int l)
     
    {
    i = malloc(sizeof(image_t));
    *i.hauteur=h;
    *i.largeur=l;
    *i.pixels=malloc((h*l+1)*sizeof(char);	
    }
    merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 963
    Points
    32 963
    Billets dans le blog
    4
    Par défaut
    Ce code ne fera rien d'autre que des fuites mémoires.
    Dans la fonction tu modifies une copie de pointeur, l'original ne sera pas modifié et n'aura jamais la nouvelle structure en mémoire.
    Au passage, plutôt que ces immondes *i., utilise l'opérateur ->
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par enzo9311 Voir le message
    Voici un exercice que je du effectué, et je voulais avoir votre avis dessus.
    Voici ce que j'ai écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void alloue_image(image_t* i, int h, int l)
     
    {
    i = malloc(sizeof(image_t));
    *i.hauteur=h;
    *i.largeur=l;
    *i.pixels=malloc((h*l+1)*sizeof(char);	
    }
    Bonjour
    Tu alloues "i" (local à la fonction) que tu perds ensuite. Bref pareil que Bousk. Mémoire allouée et perdue.

    A mon avis, tu devrais reprendre le premier programme et l'indenter correctement, tu verrais mieux où il y a l'erreur (et au passage ça te montrera que l'indentation d'un code ce n'est pas que pour faire joli).

    Citation Envoyé par enzo9311 Voir le message
    Citation Envoyé par Bousk Voir le message
    Au passage, plutôt que ces immondes *i., utilise l'opérateur ->
    D'autant plus que l'opérateur "étoile" étant moins prioritaire que le "point", pour que ça fonctionne tu aurais dû écrire (*i).membre=valeur...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre averti
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Points : 387
    Points
    387
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par enzo9311 Voir le message
    Bonjour,

    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
    typedef struct{
     
    int hauteur, largeur;
    unsigned char* pixels;
    }image_t;
     
     
    void alloue_image(image_t* i, int h, int l)
    {
    i.hauteur=h;
    i.largeur=h;
    i.pixels=malloc(h*l+1);
    }
     
    return i;
     
    }
    Voici ce que j'ai écrit:
    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
     
     
     
     
    typedef struct image_t image_t;
    struct image_t
    {
    int hauteur;
    int  largeur;
    unsigned char* pixels;
     
    };
     
    void alloue_image(image_t* i, int h, int l)
     
    {
    i = malloc(sizeof(image_t));
    *i.hauteur=h;
    *i.largeur=l;
    *i.pixels=malloc((h*l+1)*sizeof(char);	
    }
    merci d'avance
    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
     
    struct { 
        int hauteur, largeur;
        unsigned char* pixels;
    } image_t;
     
    void alloue_image( int h, int l) {
        struct image_t* i = (struct image_t *) malloc(sizeof(image_t);
     
        i->hauteur=h;
        i->largeur=h;
    }
     
    return i;
     
    }
    c'est quoi cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *i.pixels=malloc((h*l+1)*sizeof(char);
    ???
    Que cherches-tu à faire ???

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 19
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *i.pixels=malloc((h*l+1)*sizeof(char);
    c'est pour allouer la taille pour 'pixels' qui est dans la structure

  6. #6
    Membre averti
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Points : 387
    Points
    387
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par enzo9311 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *i.pixels=malloc((h*l+1)*sizeof(char);
    c'est pour allouer la taille pour 'pixels' qui est dans la structure
    Ce que tu vas obtenir sera un vecteur de h*l+1 char dont l'adresse de début sera i->pixels ?!

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par enzo9311 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *i.pixels=malloc((h*l+1)*sizeof(char);
    c'est pour allouer la taille pour 'pixels' qui est dans la structure
    Ben oui mais comme tu as mal adressé le membre "pixel" du pointeur "i" (cf mon premier post), le résultat du malloc ne sera pas récupéré au bon endroit.

    Quand on veut s'adresser à un membre "xxx" d'un pointeur de structure "pt", l'opération "membre xxx du pointé de pt" s'écrira tout logiquement (*pt).xxx (à cause des priorités des opérateurs dont j'ai déjà parlé). Parce que si tu écris *pt.xxx ça équivaut à *(pt.xxx) ce qui signifie que "pt" est la structure elle-même (et non un pointeur) et que le pointeur c'est "xxx".
    Mais l'écriture (*pt).xxx étant assez "chiante", il a été créé un opérateur de substitution "flèche". Ainsi l'écriture (*pt).xxx devient pt->xxx. C'est plus simple à écrire et ça signifie exactement la même chose (accès au membre "xxx" du pointé de "pt"). Et tout ça doit sûrement être écrit dans tes cours mais tout le monde sait évidemment qu'un cours c'est fait pour surtout ne pas être lu.

    Donc à toi de voir ce que tu préfères écrire. Tu as le choix des deux écritures mais si tu choisis la première (sait-on jamais), alors fais le correctement.

    PS: si "xxx" est lui aussi un pointeur, alors l'accès à son pointé s'écrira *(*pt).xxx ou plus simplement *pt->xxx (qui se lit alors *(pt->xxx)).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 19
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    très bien merci beaucoup. Je croyais que *i.XXX était exactement équivalent à i->xxx. Je savais pas qu'il fallait mettre des parenthèses.

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par enzo9311 Voir le message
    Je croyais que *i.XXX était exactement équivalent à i->xxx.
    Ca aurait été totalement contre-productif d'implémenter deux écritures distinctes exactement équivalentes...

    Citation Envoyé par enzo9311 Voir le message
    Je savais pas qu'il fallait mettre des parenthèses.
    Et ça ne te choquait pas d'écrire la même chose dans le cas où c'est "XXX" le pointeur et "i" la structure???
    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
    typedef strut {
    	int *xxx;
    	int v;
    } t_truc;
     
    t_truc i;
    t_truc *pt;
    i.v=10;
    i.xxx=&i.v;
    pt=&i;
    printf("v vaut %d\n", i.v);
    printf("v vaut %d\n", pt->v);
    printf("xxx vaut %d\n", *i.xxx);
    printf("xxx vaut %d\n", *pt->xxx);
    ...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    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,
    En plus de ce qui a été mentionné par les autres membres du forum j'ajouterais que si vous souhaitez vraiment allouer dynamiquement vos structures, vous avez deux possibilités. La première (pour les débutants, cela pourrait paraître compliqué.) est l'emploi d'un pointeur de pointeur, car c’est ce qui permettra à votre fonction de pouvoir modifier votre variable pointeur . La seconde est juste une fonction qui renvoie une adresse mémoire valide obtenu grâce la fonction d’allocation dynamique malloc.

    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
     
    /*
    *	Fonction d’allocations qui renvoie 
    *	deux valeurs de retours: 
    *	(0) comme échec d’allocation et 
    *	(1) une allocation réussie.
    */
    int f_alloc_a( ts_image** p){
    	*p = malloc( 1 * (sizeof *p ));
    	return *p != NULL;
    }
    /*
    *	Fonction d’allocations qui renvoie : 
    *	-> une adresse valide en cas de succès de l'allocation dynamique 
    *	-> NULL (qui est un pointeur invalide de référence)
    */
    ts_image *f_alloc_b( void ){
    	ts_image *p = NULL;
    	if( !( p = malloc(1 *sizeof *p) ) )
    		return NULL;
    	return p; 
    }

    à 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

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

Discussions similaires

  1. Structures et pointeurs
    Par Tchetch dans le forum C
    Réponses: 14
    Dernier message: 19/10/2006, 13h30
  2. Structure et pointeur
    Par Nalido dans le forum C
    Réponses: 5
    Dernier message: 08/08/2006, 15h08
  3. Copie de structure par pointeur - Problème LSB MSB
    Par the_ionic dans le forum Réseau
    Réponses: 4
    Dernier message: 17/07/2006, 15h08
  4. Structures et pointeurs
    Par mastochard dans le forum C
    Réponses: 17
    Dernier message: 25/05/2006, 11h55
  5. [structure et pointeur] problème d'affichage
    Par kitsune dans le forum C
    Réponses: 17
    Dernier message: 22/03/2006, 22h20

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