Tableau structures argument de fonctions :retour
Résolu
getudir78
Messages postés
36
Statut
Membre
-
[Dal] Messages postés 6122 Date d'inscription Statut Contributeur Dernière intervention -
[Dal] Messages postés 6122 Date d'inscription Statut Contributeur Dernière intervention -
/*
le programme compile et s'execute partiellement
lorsque allocation de memoire et initialisation des champs
sont realisees directement dans le main, ce programme fonctionne bien
lorsque allocation de memoire et initialisation des champs
sont realisees a l'aide d'une fonctions, tout semble bien se passer dans la fonction
mais apres cela, le tableau de structures n'est pas accessible dans le main
merci de m'aider a trouver l'erreur
le programme compile et s'execute partiellement
lorsque allocation de memoire et initialisation des champs
sont realisees directement dans le main, ce programme fonctionne bien
lorsque allocation de memoire et initialisation des champs
sont realisees a l'aide d'une fonctions, tout semble bien se passer dans la fonction
mais apres cela, le tableau de structures n'est pas accessible dans le main
merci de m'aider a trouver l'erreur
- /
#include <stdio.h>
#include<stdlib.h>
typedef struct personne
{
char nom[15];
int age;
float poids;
} mapersonne;
void creer_tab (int dim, mapersonne *tab) {
/*mmm initialise le tableau de structures */
int i;
printf("char = %d\n",sizeof(char));
printf("int = %d\n",sizeof(int));
printf("dim = %d\n",sizeof(float));
printf("mapersonne sizeof = %d\n", sizeof(mapersonne));
//
tab = malloc(dim*sizeof(mapersonne));
i = 0;
while ( i < dim) {
printf("donnez un nom - un age - un poids\n");
scanf("%s", tab[i].nom);
scanf("%d", &(tab[i].age));
scanf("%f", &(tab[i].poids));
printf("dans fonction creer_tab : nom = %s age = %d poids = %f\n",tab[i].nom, tab[i].age, tab[i].poids);
i++;
}
return ;
}
int main() {
int nb_pers, i;
// pointeur defini pour l'allocation dynamique de memoire
mapersonne *tab_pers_1 = NULL;
mapersonne *tab_pers_2 = NULL;
//
printf ("nombre de personnes a definir ?\n");
scanf("%d", &nb_pers);
//
// debut creation tab_pers_1 directement dans main() - tout fonctionne parfaitement
printf("debut de l'initialisatio du tableau de structures directement dans main()\n");
tab_pers_1 = malloc(nb_pers*sizeof(mapersonne));
//
i = 0;
while ( i < nb_pers) {
printf("donnez un nom - un age - un poids\n");
scanf("%s", tab_pers_1[i].nom);
scanf("%d", &(tab_pers_1[i].age));
scanf("%f", &(tab_pers_1[i].poids));
i++;
}
// impression de valeurs definies ci-dessus
for (int i = 0;i<nb_pers;i++) {
printf("nom : %s age = %d poids = %f\n",tab_pers_1[i].nom, tab_pers_1[i].age, tab_pers_1[i].poids);
}
printf("fin de l'initialisation du tableau de structures directement dans main()\n");
// fin creation tab_pers_1 directement dans main() - tout fonctionne parfaitement
//
//debut creation tab_pers_2 par la fonction creer_tab - probleme :
// les valeurs initialsees dans creer_tab(...) ne sont pas connues dans fonction creer_tab
printf("\ndebut de l'initialisation du tableau de structures par la fonction creer_tab\n");
//
creer_tab (nb_pers, tab_pers_2);
//
//impression des valeurs retournees dans le main()
// dans l'etat actuel du programme,
for (int i = 0;i<nb_pers;i++) {
printf(" valeurs retournees de creer_tab personne numero : %d nom : %s",i, tab_pers_2[i].nom);
printf(" age = %d", tab_pers_2[i].age);
printf(" poids = %f\n",tab_pers_2[i].poids);
}
printf("fin de l'initialisation du tableau de structures par la fonction creer_tab\n");
//fin creation tab_pers_2 par la fonction - probleme :
// les valeurs initialsees dans creer_tab(...) ne sont pas commues dans le main
//
return 0;
}
1 réponse
-
Salut getudir78,
Dans mainmapersonne *tab_pers_2 = NULL;
, tab_pers_2 est une variable pointeur et la valeur contenue par cette variable est NULL.
Or, tu passes cette variable àcreer_tab()
.
Comme tout passage de variable, en C, le passage d'une variable opère une copie de cette variable, sur laquelle travaille la fonction.
Donc, dans ta fonctioncreer_tab()
, lorsque tu alloues de la mémoire et que tu ranges l'adresse mémoire du bloc alloué, tu ranges l'adresse dans une autre variable pointeur (la copie), et donc la variable pointeur déclarée dans main() n'est pas modifiée et continue de pointer vers NULL.
Dal-
Pour résoudre ce problème, tu pourrais changer ton prototype et passer un pointeur sur un pointeur sur struct, et ensuite déréférencer correctement ce pointeur.
Cependant, puisque tu alloues la mémoire dans ta fonction, le passage du pointeur n'a pas trop d'intérêt, et tu te compliques vraiment la vie.
Alors, une façon beaucoup plus simple de faire est de passer juste le nombre de personnes à créer et quecreer_tab()
retourne un pointeur sur mapersonne.
Quelque chose comme cela :
#include <stdio.h> #include <stdlib.h> typedef struct personne { char nom[15]; int age; float poids; } mapersonne; mapersonne * creer_tab(int dim) { int i = 0; mapersonne * tab = NULL; tab = malloc(dim * sizeof(mapersonne)); for (i = 0; i < dim; i++) { printf("donnez un nom - un age - un poids\n"); scanf("%s", tab[i].nom); scanf("%d", &tab[i].age); scanf("%f", &tab[i].poids); } return tab; } int main(void) { int nb_pers, i; mapersonne * tab = NULL; printf ("nombre de personnes a definir ?\n"); scanf("%d", &nb_pers); tab = creer_tab(nb_pers); for (i = 0; i < nb_pers; i++) { printf(" valeurs retournees de creer_tab personne " "numero : %d nom : %s", i, tab[i].nom); printf(" age = %d", tab[i].age); printf(" poids = %f\n", tab[i].poids); } free(tab); return 0; }
Une autre façon simple de faire serait de garder ton prototypevoid creer_tab (int dim, mapersonne *tab)
, mais d'opérer l'allocation mémoire dansmain()
et donc de laisser à la fonction appelante decreer_tab()
la responsabilité d'allouer la mémoire.
Il y a une certaine logique à cette dernière approche, car la fonction appelante est aussi responsable de la libération de la mémoire (lefree()
, que tu avais d'ailleurs omis dans ton code).
Dal -
-
Génial, je suis content !
En ce qui me concerne, la première approche me rend un peu nerveux ;-)
Je lui préfère la dernière approche, qui permet de dissocier l'allocation mémoire de l'usage de l'espace alloué par la fonction. Cela me permet de mettre, dans la même fonction appelante, lemalloc()
et lefree()
... et cela me rassure de pouvoir, autant que possible, voir les deux dans la même fonction :-)
-