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 :

declaration dynamique dans une fonction


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 277
    Points : 141
    Points
    141
    Par défaut declaration dynamique dans une fonction
    Si je declare dans un programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct 
    {
    	int **matriceF;
    	int *info;
    	int *coding;
    	int *MC;
    }bloc;
    et que j'alloue la memoire de chacun des pointeurs dans une fonction
    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
    void compute_bloc (int *info, int j ,int *tailles)
    {
    	int i,longueur_bloc;
    	bloc bc;
     
    	longueur_bloc = (int) tailles[0]/tailles[3];
    	//initialisation bc.info
    	bc.info = malloc (sizeof(int) * longueur_bloc);
    	if (bc.info == NULL) printf("probleme lors de l'allocation de bc.info\n");
    	for (i=0;i<longueur_bloc;i++)
    	{
    		bc.info[i] = info[tailles[3]*i + j];
    	}
     
     
    bc.matriceF = malloc (sizeof( int *) * longueur); 
    if(bc.matriceF==NULL) 
      { 
      // Gestion de l'erreur 
      } 
    for (i=0;i<longueur;i++) 
    { 
    bc.matriceF[i] =  malloc (sizeof( int ) * largeur); 
    if(bc.matriceF[i]==NULL) 
      { 
      // Gestion de l'erreur 
      } 
    }
    est ce que une fois revenu dans le programme principal je peux lire
    par exemple bc.matriceF[k]
    sans risque que les donnees ont ete effacées????

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 87
    Points : 63
    Points
    63
    Par défaut
    Une fois revenu dans le programme principal, bc n'existe plus car tu declares bc en de type bloc en variable locale.

    A la sortie de ta fonction, bc sera detruit (mais pas tout ce que tu as alloue entre temps qui sera zombi dans la memoire).

    Si tu veux pouvoir garder la main sur ta structure, declare bloc* bc, malloc bc, et return bc.

    Tu pourras alors acceder a tes donnees.
    Busy 999

  3. #3
    Membre habitué Avatar de Process Linux
    Inscrit en
    Septembre 2003
    Messages
    136
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 136
    Points : 149
    Points
    149
    Par défaut
    Ton programme est inpécable, il manque un petit détail , c'est que tu as déclaré la variable bc dans le corps de la fonction , donc tu vas perdres le pointeur vers la matrice une fois que tu as quitté cette fonction, pour résoudre le problème voici le code qu'il faut mettre :

    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
     
    void compute_bloc (int *info, int j ,int *tailles,bloc * bc) 
    { 
       int i,longueur_bloc; 
     
       longueur_bloc = (int) tailles[0]/tailles[3]; 
       //initialisation bc.info 
       bc->info = malloc (sizeof(int) * longueur_bloc); 
       if (bc->info == NULL) printf("probleme lors de l'allocation de bc.info\n"); 
       for (i=0;i<longueur_bloc;i++) 
       { 
          bc->info[i] = info[tailles[3]*i + j]; 
       } 
     
     
    bc->matriceF = malloc (sizeof( int *) * longueur); 
    if(bc->matriceF==NULL) 
      { 
      // Gestion de l'erreur 
      } 
    for (i=0;i<longueur;i++) 
    { 
    bc->matriceF[i] =  malloc (sizeof( int ) * largeur); 
    if(bc->matriceF[i]==NULL) 
      { 
      // Gestion de l'erreur 
      } 
    }
    en suite pour appeler la fonction il faut déclarer la variable bc ailleur, et passer la variable par adresse avec l'opérateur & .

  4. #4
    Membre actif Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Points : 203
    Points
    203
    Par défaut
    une autre solution est de déclarer
    dans ton programme principal, et de passer un pointeur vers bc comme paramètre de ta fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void compute_bloc (int *info, int j ,int *tailles, bloc *pBc);
    (quand tu appelles ta fonction, tu passes l'adresse de bc
    ensuite, ta fonction reste la même. Mais il faut changer les
    par des
    puisqu'on manipule un pointeur vers un bloc et non plus bloc.


    EDIT: Argh! j'ai été trop lent!

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 277
    Points : 141
    Points
    141
    Par défaut
    je récapitule, je déclare mes fonctions et ma structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void compute_F(int*, int, struct *);
    void computeFD(int,int *, struct *);
    typedef struct 
    {
    	int **matriceF;
    	int *info;
    	int *coding;
    	int *MC;
    }bloc;
    Dans le main je déclare *bc:
    lors de l'appel de fonction, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	compute_F(tailles, NW, &bc);
    	computeFD(NW, tailles, &bc);
    Avec cette configuration j'ai aucune erreur du compilateur par contre j'ai des warning:
    formal parameter 3 different from declaration
    warning C4047: 'function' : 'struct $S3 *' differs in levels of indirection from 'struct bloc ** '
    'computeFD' : different types for formal and actual parameter 3

    et bien souvent les warning annoncent des problemes.....

  6. #6
    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 gronaze
    je récapitule, je déclare mes fonctions et ma structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void compute_F(int*, int, struct *);
    void computeFD(int,int *, struct *);
    typedef struct 
    {
    	int **matriceF;
    	int *info;
    	int *coding;
    	int *MC;
    }bloc;
    Dans le main je déclare *bc:
    Personne ne t'a dis de faire ça, mais plutôt :

    1 - définir le type de la structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    typedef struct 
    {
    	int **matriceF;
    	int *info;
    	int *coding;
    	int *MC;
    }
    bloc_s;
    2 - définir les prototypes des fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    void compute_F(int*, int, bloc_s *);
    void computeFD(int,int *, bloc_s *);
    Nota : 1 et 2 sont placés dans un header (.h) en cas de compilation séparée

    3 - dans l'application (main, par exemple) inclure le header precédemment décrit si necessaire, définir une instance de la structure et passer son adresse aux fonctions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    {
       bloc_s bc;
       int x;
       int y;
     
       compute_F(&x, 456, &bc);
       computeFD(789, &y, &bc);
     
    }
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Juste une remarque sur ce qui a été dis précédement

    Et si je ne m'abuse, Process Linux à dis :
    Ton programme est inpécable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     if (bc->info == NULL) printf("probleme lors de l'allocation de bc.info\n");
       for (i=0;i<longueur_bloc;i++)
       {
          bc->info[i] = info[tailles[3]*i + j];
       }
    J'ai une petite remarque a emettre : le programme n'est pas si impec que cela ... (en tout cas pour moi ...) En fait, tu fais ton malloc et s'il plantes, tu le signales mais aussitôt après, tu fais comme si tout c'était bien déroulé, c'est embêtant. Le mieux, c'est de ne pas effectuer les opérations pour éviter les plantages (soit tu quittes le programme, soit tu gère celà autrement, ...)

    De plus, lorsque ça va planter (et ça va planter, cf Murphy ...), tu ne le saura pas au bon moment, ceci étant du au printf qui est bufferisé. La meilleure solution consiste à effectuer un fprintf sur la sortie d'erreur (stderr), du coup, c'est non buffurisé et celà correspond comme le nom l'indique à une sortie d'erreur, ce qui correspond bien au sujet.

    Sinon, pour le reste, rien à rajouter à ce qui a été dis

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 277
    Points : 141
    Points
    141
    Par défaut
    ok merci.
    C'est vrai que c'est mieux d'utiliser un header.


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

Discussions similaires

  1. SQL dynamique dans une fonction définie par l'utilisateur
    Par messalux dans le forum Développement
    Réponses: 7
    Dernier message: 11/11/2010, 09h25
  2. Variables dynamiques dans une fonction
    Par NiGHtyWolf dans le forum Langage
    Réponses: 1
    Dernier message: 31/01/2010, 14h38
  3. Allocation dynamique dans une fonction
    Par n0mad dans le forum Débuter
    Réponses: 5
    Dernier message: 05/02/2009, 22h42
  4. nombre des variables dynamique dans une fonction
    Par Abdelkaoui dans le forum C
    Réponses: 10
    Dernier message: 29/02/2008, 15h37
  5. variable dynamique dans une fonction javascript
    Par Shivaneth dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 20/04/2005, 15h58

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