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 :

Structure, pointeur et fonction...


Sujet :

C

  1. #1
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut Structure, pointeur et fonction...
    Bonsoir,

    J'ai un problème avec mon programme.
    Alors j'ai un .h avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct CLIENT {
      int * t_num;
      float * t_achats;
      int nb_max_clients;
    };
     
    typedef struct CLIENT TAB_CLIENTS;
     
    void init (int, TAB_CLIENTS *);
    C'est le fait de passer ma variable structure en pointeur à la fonction init qui pose problème!

    Ma fonction init :
    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
    void init (int max_clients, TAB_CLIENTS * cli) {
     
      // declarations
      int i, num[max_clients];
      float achats[max_clients];
     
      cli->nb_max_clients=max_clients;
     
      // initialisation des numeros
      for(i=0;i<max_clients;i++)
        num[i]=0;
      cli->t_num = num;
     
      // initialisation des achats
      for(i=0;i<max_clients;i++)
        achats[i]=0.0;
      cli->t_achats = achats;
     
      // test d'affichage
      for(i=0;i<cli->nb_max_clients;i++)
        printf("n° %d : %f\n",cli->t_num[i],cli->t_achats[i]);
     
      printf("\n\n");
    }
    Avec le test d'affichage, tout est ok, ma variable structure est bien initialisée!

    Le problème est dans mon main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main () {
      // declarations
      int i;
      TAB_CLIENTS les_clients;
     
      // appel a la fonction
      init(10,&les_clients);
     
      // test d'affichage qui foire!
      for(i=0;i<les_clients.nb_max_clients;i++)
        printf("n° %d : %f\n",les_clients.t_num[i],les_clients.t_achats[i]);
     
      return 0;
    }
    La variable les_clients que je recupère devrait etre initialisée, mais en fait elle l'est à moitié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    0 : 0.00000032 : 0.0000001107378272 : 0.0000001108287296 : 0.0000000 : 0.0000000 : 0.0000000 : 0.0000000 : 0.0000000 : 0.0000000 : 0.000000
    J'ai réduit le nombre max, mais avec 30 par ex, c'est pire ! Il y a meme des nombres negatifs qui apparaissent!
    Je ne vois pas où est l'erreur ?! Si vous pouvez m'éclairer.

    Merci

  2. #2
    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
    euh... TU passes à ta structure l'adresse de variables locales automatiques: quand tu quittes la fonction init(), c'est comme si elles n'existaient plus --> comportement indéfini, le plus souvent des trucs pas bien.
    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.

  3. #3
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    Comment puis-je faire alors pour initialiser mes 2 tableaux ?

    J'ai essayé ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for(i=0;i<max_clients;i++)
        cli->t_num[i] = 0;
     
      for(i=0;i<max_clients;i++)
        cli->t_achats[i] = 0.0;
    Mais cela ne fonctionne pas

  4. #4
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Citation Envoyé par Linaa
    Comment puis-je faire alors pour initialiser mes 2 tableaux ?

    J'ai essayé ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for(i=0;i<max_clients;i++)
        cli->t_num[i] = 0;
     
      for(i=0;i<max_clients;i++)
        cli->t_achats[i] = 0.0;
    Mais cela ne fonctionne pas
    Ben c'est normal, il faut quand même allouer de la mémoire pour stocker ces valeurs....
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  5. #5
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    Citation Envoyé par Pouic
    Ben c'est normal, il faut quand même allouer de la mémoire pour stocker ces valeurs....
    Euh... quelles valeurs ??

  6. #6
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Citation Envoyé par Linaa
    Citation Envoyé par Pouic
    Ben c'est normal, il faut quand même allouer de la mémoire pour stocker ces valeurs....
    Euh... quelles valeurs ??
    Dans ta struct CLIENT, tes pointeurs ne sont pas initialisés... Et après, tu espère mettre des valeurs via tes boucles...Ceci ne peut que planter si tu n'as pas fait le malloc qui va bien auparavant...
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  7. #7
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    Je vois...

    Mais dans ma structure CLIENT
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct CLIENT {
      int * t_num;
      float * t_achats;
      int nb_max_clients;
    };
    t_num et t_achats sont des tableaux dont je veux fixer la taille à max_clients, qui peut varier.
    C'est pour cela que je passe par des pointeurs, sinon j'aurais fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct CLIENT {
      int  t_num[10];
      float t_achats[10];
      int nb_max_clients;
    };
    En fait j'voudrais un pointeur sur un tableau de taille max_clients.
    Ce que j'ai fait au début, mais à la sortie de la fonction, plus rien...

  8. #8
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Citation Envoyé par Linaa
    Je vois...

    Mais dans ma structure CLIENT
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct CLIENT {
      int * t_num;
      float * t_achats;
      int nb_max_clients;
    };
    t_num et t_achats sont des tableaux dont je veux fixer la taille à max_clients, qui peut varier.
    Et qu'est ce qui te pose problème avec malloc ??
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct CLIENT t;
    t.max_clients = 10;
    t.t_num = malloc (t.max_clients);
    if (!t.t_num){
    ....
    }
    :
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  9. #9
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    En fait j'y pensais pas au malloc!
    Mais j'ai pas trop compris, ça alloue une taille de 10 octets (dans l'exemple) c'est ça ??
    Sinon, ça fonctionne.

    Mais là, j'ai aussi un problème de free
    En faisant dans le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    free (les_clients.t_num);
    Me suis-je trompée ?

  10. #10
    Membre averti Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Points : 396
    Points
    396
    Par défaut
    Citation Envoyé par Linaa
    En fait j'y pensais pas au malloc!
    Mais j'ai pas trop compris, ça alloue une taille de 10 octets (dans l'exemple) c'est ça ??
    Sinon, ça fonctionne.

    Mais là, j'ai aussi un problème de free
    En faisant dans le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    free (les_clients.t_num);
    Me suis-je trompée ?
    Ca te fais quoi comme erreur ? chunk pointer ou not allocated memory ? ou pire ?
    Don't worry, be serious.
    La vie est courte. Prenez votre temps.

    Jack.

  11. #11
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    Pire !! Enfin, je ne sais pas à quoi cela peut etre dû

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** free(): invalid next size (fast): 0x0804a008 ***
    Abandon

  12. #12
    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 Linaa
    Pire !! Enfin, je ne sais pas à quoi cela peut etre dû

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** free(): invalid next size (fast): 0x0804a008 ***
    Abandon
    J'ai un peu du mal à suivre.



    Montre le code complet, compilable mais réduit au minimum qui montre le problème (avec malloc() / free()).
    Pas de Wi-Fi à la maison : CPL

  13. #13
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    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
    void init (int max_clients, TAB_CLIENTS * cli) {
     
      int i, num[max_clients];
      float achats[max_clients];
     
      cli->nb_max_clients=max_clients;
     
      [b]cli->t_num = malloc (max_clients);[/b]
      for(i=0;i<max_clients;i++)
        cli->t_num[i]=0;
     
      [b]cli->t_achats = malloc (max_clients);[/b]
      for(i=0;i<max_clients;i++)
        cli->t_achats[i]=0.0;
     
      printf("\n\n");
    }
     
    int main () {
     
      int i;
      TAB_CLIENTS les_clients;
     
      init(10,&les_clients);
     
      les_clients.t_num[0] = 1;
      les_clients.t_achats[0] = 23.4;
     
      for(i=0;i<les_clients.nb_max_clients;i++)
        printf("n° %d : %f\n",les_clients.t_num[i],les_clients.t_achats[i]);
     
      [b]free (les_clients.t_num);
      free (les_clients.t_achats);[/b]
     
      return 0;
    }
    La structure est celle de mon premier post

  14. #14
    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 Linaa
    La structure est celle de mon premier post
    Ok.


    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
     
    main.c:18: error: implicit declaration of function `malloc'
    main.c:18: warning: nested extern declaration of `malloc'
    <internal>:0: warning: redundant redeclaration of 'malloc'
    main.c:18: warning: passing arg 1 of `malloc' as unsigned due to prototype
    main.c:22: warning: passing arg 1 of `malloc' as unsigned due to prototype
    main.c:26: error: implicit declaration of function `printf'
    main.c:26: warning: nested extern declaration of `printf'
    <internal>:0: warning: redundant redeclaration of 'printf'
    main.c:13: warning: unused variable `num'
    main.c:14: warning: unused variable `achats'
    main.c: At top level:
    main.c:29: warning: function declaration isn't a prototype
    main.c: In function `main':
    main.c:40: warning: nested extern declaration of `printf'
    <internal>:0: warning: redundant redeclaration of 'printf'
    main.c:42: error: implicit declaration of function `free'
    main.c:42: warning: nested extern declaration of `free'
    Merci de poster du code COMPILABLE.

    Ton code fonctionne, mais les données sont mal organisées. Je propose ç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
     
    /* x.h */
    #ifndef H_X
    #define H_X
     
    struct client
    {
        int num;
        float achats;
    };
     
    struct TAB_CLIENTS
    {
        struct client *a;
        size_t nb;
    };
     
    int init (size_t nb, struct TAB_CLIENTS *);
     
    #endif
    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
     
    /* x.c */
    #include <stdlib.h>
     
    #include "x.h"
     
    int init (size_t max_clients, struct TAB_CLIENTS *p_cli)
    {
        int err=0;
        int i;
     
        p_cli->nb=max_clients;
     
        p_cli->a = malloc (max_clients);
     
        if (p_cli->a != NULL)
        {
     
            for(i=0;i<p_cli->nb;i++)
            {
                p_cli->a[i].num=0;
                p_cli->a[i].achats=0.0;
            }
        }
        else
        {
            err=1;
        }
        return err;
    }
    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 "x.h"
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main (void)
    {
        struct TAB_CLIENTS les_clients = {0};
     
        init(10,&les_clients);
     
        les_clients.a[0].num = 1;
        les_clients.a[0].achats = 23.4;
     
        {
            int i;
            for(i=0;i<les_clients.nb;i++)
            {
                printf("%d : %f\n"
                ,les_clients.a[i].num
                ,les_clients.a[i].achats);
            }
        }
        free (les_clients.a), les_clients.a=NULL;
     
        return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  15. #15
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include <stdio.h>
    #include "client.h"
    #include <stdlib.h>
    Dans le fichier client.h (la structure + prototype de la fonction)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct CLIENT {
      int * t_num;
      float * t_achats;
      int nb_max_clients;
    };
     
    typedef struct CLIENT TAB_CLIENTS;
     
    void init (int, TAB_CLIENTS *);

  16. #16
    Membre expérimenté
    Avatar de Linaa
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    987
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 987
    Points : 1 309
    Points
    1 309
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ton code fonctionne, mais les données sont mal organisées.
    Mais pourquoi de mon côté ça ne fonctionne pas ?!
    A quoi correspond cette erreur ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** glibc detected *** free(): invalid next size (fast): 0x0804a008 ***
    Abandon

Discussions similaires

  1. structure / pointeur sur fonction
    Par fd_caramba dans le forum Débuter
    Réponses: 4
    Dernier message: 28/09/2008, 18h06
  2. Réponses: 9
    Dernier message: 14/01/2007, 16h40
  3. structures et pointeurs de fonctions
    Par aimad41 dans le forum C
    Réponses: 5
    Dernier message: 21/11/2006, 10h49
  4. Réponses: 10
    Dernier message: 04/01/2006, 16h57
  5. Pointeur de fonction et structure
    Par Trunks dans le forum C
    Réponses: 6
    Dernier message: 07/10/2005, 00h32

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