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 :

déclarer et initialiser de l'espace depuis une fonction


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2009
    Messages : 46
    Par défaut déclarer et initialiser de l'espace depuis une fonction
    Bonjour,

    j'aimerai créer un tableau "population" qui contiendrait plusieurs variables de type "Famille"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct Famille Famille;
    struct Famille{
            int nIndividus; // nombre d'individus dans la famille
            int* ages;      // leurs ages
    };
    Dans mes messages précédents, j'allouais l'espace mémoire dans le main, mais j'aimerai rendre la chose plus élégante en le faisant via une fonction appelée ici "initialisePopulation".
    Le code compile, mais à l'éxécution j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ~/Documents/C/famille$ ./test 20 2
    Erreur de segmentation (core dumped)
    .

    Je ne vois pas d'où vient le problème, pensant faire tous les "free" nécessaires.

    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
    37
    38
    39
    40
    41
    42
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct Famille Famille;
    struct Famille{
            int nIndividus; // nombre d'individus dans la famille
            int* ages;      // leurs ages
    };
     
    void initialisePopulation(Famille* population, int nFamilles, int nIndividus);
    void viderMemoire(Famille* population, int nFamilles);
     
    int main(int argc, char* argv[]){
            int nFamilles = 0;
            int nIndividus = 0;
            nFamilles = atoi(argv[1]);
            nIndividus = atoi(argv[2]);
     
            Famille* population = NULL;     // une population = plusieurs familles
     
            initialisePopulation(population, nFamilles, nIndividus);
     
            viderMemoire(population, nFamilles);
            free(population);
            return(0);
    }
     
    void initialisePopulation(Famille* population, int nFamilles, int nIndividus){
            int i = 0;
            population = malloc(nFamilles * sizeof(Famille));
            for(i=0; i<nFamilles; i++){
                    population[i].ages = NULL;
                    population[i].ages = malloc(nIndividus * sizeof(int));  // on suppose toutes les familles de même taille pour faire simple
            }
    }
     
    void viderMemoire(Famille* population, int nFamilles){
            int i = 0;
            for(i=0; i<nFamilles; i++){
                    free(population[i].ages);
            }
    }
    Merci beaucoup pour vos remarques !

    M.

  2. #2
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    791
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 791
    Par défaut
    Hello,

    Tu dois passer à initialisePopulation(....) l'adresse de population, et non population. En C, les variables sont passées par valeur, donc le population du main(....) n'a rien à voir avec le population de initialisePopulation(....) (si ce n'est que le nom et le type sont les mêmes):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void initialisePopulation(Famille **population, int nFamilles, int nIndividus){
            int i = 0;
            *population = malloc(nFamilles * sizeof(Famille));
            for(i=0; i<nFamilles; i++){
                    (*population)[i].ages = NULL; // --> pourquoi cette ligne
                    (*population)[i].ages = malloc(nIndividus * sizeof(int));  // on suppose toutes les familles de même taille pour faire simple
            }
    }
    et donc l'appel devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    initialisePopulation(&population, nFamilles, nIndividus);
    A+
    Edgar;

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Tu en es déjà à gérer des structures et des zones allouées. Tu dois donc connaitre les bases. Or, une de ces bases dit que si tu veux que ta fonction ait possibilité de modifier une variable de type "truc" (exemple truc toto), alors tu dois passer l'adresse de ta variable à ta fonction, laquelle la stockera dans un pointeur de type truc *pt.

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
        int i=5;
        modif(&i);
    }
     
    void modif(int *pt)
    {
        (*pt)=10;  // "*pt" fait référence à ce qui est "à l'adresse dont la valeur est dans pt" donc à la variable "i" elle-même
    }

    Ben cette règle reste la même même si ta variable d'origine est déjà un pointeur. Après-tout, un pointeur est une variable comme une autre...
    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
        char *zone;
        alloue(&zone, 10);
    }
     
    void alloue(char **pt, int n)
    {
        (*pt)=malloc(n * sizeof(char));  // De même "*pt" fait référence à ce qui est "à l'adresse dont la valeur est dans pt" donc ici à la variable "zone" elle-même (qui est peut-être un pointeur ce qui ne change rien au mécanisme)
    }

    Autre remarque: si tu veux faire les choses élégemment, essaye alors de nommer ton type "t_famille" ce qui te permettra d'utiliser le token "famille" pour un nom de variable (de type "t_famille")...
    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]

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/12/2006, 11h37
  2. Initialiser un champ texte avec une fonction javascript
    Par Agoye dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 20/06/2006, 11h26
  3. [AS2] Atteindre attribut d'une classe depuis une fonction interne a la classe
    Par Demco dans le forum ActionScript 1 & ActionScript 2
    Réponses: 6
    Dernier message: 18/04/2006, 21h03
  4. Retourner un tableau depuis une fonction
    Par obalais dans le forum C++
    Réponses: 2
    Dernier message: 20/10/2005, 16h49
  5. Ecrire dans un tableau html depuis une fonction js ?
    Par botanica dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/10/2005, 12h48

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