[C] problème avec la fonction realloc()
Résolu/Fermé
iunity
Messages postés
74
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
16 mai 2013
-
24 sept. 2008 à 13:53
iunity Messages postés 74 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 16 mai 2013 - 24 sept. 2008 à 21:31
iunity Messages postés 74 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 16 mai 2013 - 24 sept. 2008 à 21:31
11 réponses
iunity
Messages postés
74
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
16 mai 2013
9
24 sept. 2008 à 16:10
24 sept. 2008 à 16:10
J'ai fais ce que tu m'as dit, et maintenant j'ai un problème à la compilation. J'ai des warnings aux lignes
J'ai le message :
Et à l'exécution j'ai une erreur de segmentation.
ChargeObjet("./test.obj", &Monde, &Objet);et
ChargeObjet("./test2.obj", &Monde, &Objet2);
J'ai le message :
test.c: Dans la fonction «main» : test.c:277: attention : passing argument 3 of «ChargeObjet» from incompatible pointer type test.c:280: attention : passing argument 3 of «ChargeObjet» from incompatible pointer type
Et à l'exécution j'ai une erreur de segmentation.
Bonjour
Objets est-il un pointeur, ou un pointeur sur un pointeur ?
D'après ta première ligne, c'est un pointeur sur un pointeur, puisque tu alloues par *Tout->Objets=malloc(sizeof(Objet)); et non pas simplement Tout->Objets=malloc(sizeof(Objet));
Dans ce cas, *Tout->Objets est un pointeur, et sizeof (*Tout->Objets) c'est la taille du pointeur , pas de la zone pointée. Donc sizeof(*Tout->Objets)+sizeof(Objet)); ça ne veut pas dire grand chose.
Je crois (pas sûr) que le seul moyen est de mémoriser dans une autre variable la taille déjà allouée, et de la mettre à jour à chaque realloc (et free)
Objets est-il un pointeur, ou un pointeur sur un pointeur ?
D'après ta première ligne, c'est un pointeur sur un pointeur, puisque tu alloues par *Tout->Objets=malloc(sizeof(Objet)); et non pas simplement Tout->Objets=malloc(sizeof(Objet));
Dans ce cas, *Tout->Objets est un pointeur, et sizeof (*Tout->Objets) c'est la taille du pointeur , pas de la zone pointée. Donc sizeof(*Tout->Objets)+sizeof(Objet)); ça ne veut pas dire grand chose.
Je crois (pas sûr) que le seul moyen est de mémoriser dans une autre variable la taille déjà allouée, et de la mettre à jour à chaque realloc (et free)
iunity
Messages postés
74
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
16 mai 2013
9
24 sept. 2008 à 14:29
24 sept. 2008 à 14:29
En fait ça se structure comme ça :
*Objets[] est un tableau de pointeurs vers la structure Objet. A chaque fois que j'ajoute une valeur dans Objets[], j'exécute le code suivant :
Le code se trouve dans une fonction, et comme la structure Objet contient des gros éléments, j'ai préféré utiliser les pointeurs pour éviter de tout passer en paramètres.
La création du premier objet se passe bien, mais au deuxième ça plante.
J'ai essayé de mémoriser la taille déjà allouée, mais ça n'a pas marché. J'ai même essayer de mettre la taille en dur dans le programme :
et de ne charger que deux objets, mais ça ne marche toujours pas.
struct Tout { int NbObjets; struct Objet *Objets[]; }; struct Objet { [...] };
*Objets[] est un tableau de pointeurs vers la structure Objet. A chaque fois que j'ajoute une valeur dans Objets[], j'exécute le code suivant :
if(Monde->NbObjets==0) { *Monde->Objets=malloc(sizeof(Objet)); } else { *Monde->Objets=realloc(*Monde->Objets, taille+sizeof(Objet)); }
Le code se trouve dans une fonction, et comme la structure Objet contient des gros éléments, j'ai préféré utiliser les pointeurs pour éviter de tout passer en paramètres.
La création du premier objet se passe bien, mais au deuxième ça plante.
J'ai essayé de mémoriser la taille déjà allouée, mais ça n'a pas marché. J'ai même essayer de mettre la taille en dur dans le programme :
if(Monde->NbObjets==0) { *Monde->Objets=malloc(4); } else { *Monde->Objets=realloc(*Monde->Objets, 8); }
et de ne charger que deux objets, mais ça ne marche toujours pas.
Comment Monde est-il déclaré et initialisé ?
Pourquoi as-tu défini Objets comme un tableau de pointeurs ? Si tu agrandis la zone allouée à chaque fois au lieu d'allouer une nouvelle zone, tu n'as pas besoin d'un tableau et du devrais écrire Monde->Objets = malloc ou realloc
Pourquoi as-tu défini Objets comme un tableau de pointeurs ? Si tu agrandis la zone allouée à chaque fois au lieu d'allouer une nouvelle zone, tu n'as pas besoin d'un tableau et du devrais écrire Monde->Objets = malloc ou realloc
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
iunity
Messages postés
74
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
16 mai 2013
9
24 sept. 2008 à 15:27
24 sept. 2008 à 15:27
Tout d'abord je viens de remarquer une erreur dans le code précédent. J'ai décidé de renommer la variable Tout en Monde car je ne la trouvait pas assez parlante. La première structure s'appelle désormais Monde (pas comme je l'ai écrit).
Sinon, pour être plus clair, mon code ressemble à ça :
Objets est un tableau de pointeurs car au final la structure Objet contiendra aussi un tableau dynamique, et il me semble que c'est le seul moyen de faire.
Je précise aussi que j'ai déjà essayé mon programme avec un tableau statique, et qu'il marche bien (mais je dois allouer de gros tableaux pour parfois pas grand chose).
Dernière précision : normalement ça n'a pas d'importance, mais je code sous Linux.
Sinon, pour être plus clair, mon code ressemble à ça :
struct Objet { int var1, var2, var3[...] }; struct Monde { int NbObjets; struct Objet *Objets[]; }; void ChargeObjet(char *Chemin, struct Monde *Monde, struct Objet *Objet) { if(Monde->NbObjets==0) *Monde->Objets=malloc(sizeof(Objet)); else *Monde->Objets=realloc(*Monde->Objets, sizeof(*Monde->Objets)+sizeof(Objet)); Objet->var1=42; [...] Monde->Objets[Monde->NbObjets]=Objet; Monde->NbObjets++; } main() { struct Monde Monde; Monde.NbObjets=0; struct Objet Objet; ChargeObjet("./test.obj", &Monde, &Objet); struct Objet Objet2; ChargeObjet("./test2.obj", &Monde, &Objet2); [...] }
Objets est un tableau de pointeurs car au final la structure Objet contiendra aussi un tableau dynamique, et il me semble que c'est le seul moyen de faire.
Je précise aussi que j'ai déjà essayé mon programme avec un tableau statique, et qu'il marche bien (mais je dois allouer de gros tableaux pour parfois pas grand chose).
Dernière précision : normalement ça n'a pas d'importance, mais je code sous Linux.
En fait, tu n'alloues qu'un pointeur à chaque fois, pas une structure Object ! Tes structures sont statiques.
Tu devrais donc déclarer struct Objet **Objets;
et à chaque malloc / realloc allouer une taille de sizeof( struct Object *)
Tu devrais donc déclarer struct Objet **Objets;
et à chaque malloc / realloc allouer une taille de sizeof( struct Object *)
*Monde->Objets=malloc(sizeof(struct Object *)); ou *Monde->Objets=realloc(*Monde->Objets, (Monde->NbObjets+1) * sizeof(struct Object *));
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
24 sept. 2008 à 16:33
24 sept. 2008 à 16:33
as tu pensé à allouer Monde->Objets ? il faut que tu lui dise sur combien de tableaux tu comptes le faire pointé.
J'aurai écrit
Monde->Objets=malloc(sizeof(struct Object *));
ou
Monde->Objets=realloc(*Monde->Objets, (Monde->NbObjets+1) * sizeof(struct Object *));
J'aurai écrit
Monde->Objets=malloc(sizeof(struct Object *));
ou
Monde->Objets=realloc(*Monde->Objets, (Monde->NbObjets+1) * sizeof(struct Object *));
S'il te plaît, ne fais pas de modifications parce que je te le dis, mais parce que tu comprends pourquoi il faut les faire.
Tu as dû modifier autre chose par rapport au code que tu donnes dans le message 4. Dans ce message, le 3ème paramètre est struct Objet *Objet et tu passes bien à l'appel l'adresse d'une struc Objet. On ne peut pas faire plus compatible
Peut-être as-tu mal compris la modif que je te demandais, qui concerne la définition du champ Objets dans la structure Tout ?
Tu as dû modifier autre chose par rapport au code que tu donnes dans le message 4. Dans ce message, le 3ème paramètre est struct Objet *Objet et tu passes bien à l'appel l'adresse d'une struc Objet. On ne peut pas faire plus compatible
Peut-être as-tu mal compris la modif que je te demandais, qui concerne la définition du champ Objets dans la structure Tout ?
iunity
Messages postés
74
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
16 mai 2013
9
24 sept. 2008 à 17:43
24 sept. 2008 à 17:43
Effectivement j'avais mal compris ce que tu avais dit. Maintenant ça a l'air de marcher. Mais il reste encore un problème, à la ligne
qui provoque un warning a la compilation et une grosse erreur à l'exécution.
Monde->Objets[Monde->NbObjets]=Objet;
qui provoque un warning a la compilation et une grosse erreur à l'exécution.
Je n'ai pas le temps de vérifier. Il me semble que quelque chose comme
serait préférable
(Monde->Objets)[Monde->NbObjets]=Objet;
serait préférable
iunity
Messages postés
74
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
16 mai 2013
9
24 sept. 2008 à 21:31
24 sept. 2008 à 21:31
Ta ligne ne marche pas, mais j'ai utilisé
Je te remercie beaucoup pour ton aide.
(*Monde->Objets)[Monde->NbObjets]=Objet;et là ça marche très bien. Je marque donc le sujet comme résolu.
Je te remercie beaucoup pour ton aide.