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 :

Constructeur de structure qui ne fonctionne pas correctement dans une methode


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut Constructeur de structure qui ne fonctionne pas correctement dans une methode
    Bonjour a tous, voici ma structure:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CourbeBezierPtr CourbeBezierConstructeur (int Dimension, int Degre)
    {
    	CourbeBezierPtr CBPtr;
    	CBPtr = (CourbeBezierPtr)malloc(sizeof(CourbeBezier));
    	CBPtr->Dimension=Dimension;
    	CBPtr->Degre=Degre;
    	CBPtr->Ordre=Degre+1;
    	int i;
    	for (i=0; i<Dimension; i++)
    	{
    		CBPtr->Poles[i] = VecteurConstructeur(CBPtr->Ordre);
    	}
    	return CBPtr;
    }
    Et la methode a l'interieur de laquelle elle est utilisee:

    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
    CourbeBezierPtr ConstruitCourbe (int Dimension, int NbPoints, int Degre, VecteurPtr Points[])
    {
    	if (NbPoints==Degre+1)
    	{
    		CourbeBezierPtr C = CourbeBezierConstructeur(Dimension, Degre);
    		printf("C->Degre=%d",C->Degre);
    		MatricePtr M = MatriceConstructeur(NbPoints,C->Ordre);
    		double* A = ConstruitParametres(Dimension, NbPoints, Points);
    		int i,j,k;
    		for (i=0; i<NbPoints; i++)
    		{
    			for (j=0; j<(C->Ordre); j++)
    			{
    				printf("A[%d]=%f, C->Degre=%d, j=%d\n",i,A[i],C->Degre,j);
    				M->Coef2d[i][j] = EvalueBernstein(C->Degre, j, A[i]);
    			}
    		}
    //...
    Enfin, la ligne du main:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CourbeBezierPtr C2 = ConstruitCourbe(3,3,2,Points);
    Resultat:

    C->Degre vaut 0 !!!!!!!?????

    Ca fait toute la matinee que je planche dessus et personne pour m'aider dans mon entourage! Par pitie, si vous avez une idee... :'(

    Merci d'avance

  2. #2
    Membre actif Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Points : 223
    Points
    223
    Par défaut
    Bonjour,

    Ce serait peut-être utile de faire figurer le code de la structure courbe de Bezier.
    A priori ici il y a un petit problème, dans CourbeBezierConstructeur, vous remplissez un tableau pole avec Dimensions éléments alors qu'a priori la Dimension est variable vous n'avez donc pas pu prévoir sa taille à l'avance dans la déclaration de votre structure, il vaut manque donc une allocation mémoire pou ce tableau.
    Une autre solution pourrait être que la condition de continuation de la boucle n'est pas celle que vous vouliez mettre.
    Votre problème est donc sans doute une fuite mémoire.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    Effectivement, j'ai mis le code du constructeur au lieu de la structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct courbe_bezier
    {
      int Degre;
      int Dimension;	
      int Ordre;
      VecteurPtr Poles[3];
    } CourbeBezier, *CourbeBezierPtr;
    Par contre, je n'ai pas tres bien compris ton message. La Dimension est statique, puisqu'elle est entree en parametre, alors ou est-ce que je n'ai pas alloue ce qu'il faut?

  4. #4
    Membre actif Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Points : 223
    Points
    223
    Par défaut
    Dans la fonction "CourbeBezierConstructeur" tu fais CBtr->Pole[i] aveC i variant de 0 à "Dimension", comme je suppose que tu utiliseras "Dimension" <=3, il n'y aura donc pas le problème que j'ai précédemment évoqué.

  5. #5
    Membre actif Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Points : 223
    Points
    223
    Par défaut
    Le problème est peut-être dû à une fuite mémoire dans la fonction "VecteurConstructeur"

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    Qu'est-ce que tu appelles "fuite de memoire"? Un depassement de limite du tableau (un Segmentation Fault, donc)?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    VecteurPtr VecteurConstructeur(int n)
    {
      VecteurPtr V=NULL;
     
      if (n>0)
        {
          int i;
          V=(VecteurPtr)malloc(sizeof(Vecteur)); 
          V->N=n; 
          V->Coord=(double*)malloc(n*sizeof(double)); 
        } 
      return V;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct Vect 
    {
      int N ;
      double*Coord ;
    }Vecteur,*VecteurPtr;
    Je ne crois pas que l'erreur vienne de la, car j'ai maintes fois utilise les structures Vecteur dans mon programme et je n'ai jamais eu de problemes avec (la mon programme touche a sa fin).

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    Erreur d'enonce:

    J'avais mal interprete mon code! En fait, c'est apres l'appel de ConstruitParametres que C->Degre est injustement reinitialise a 0, pas la ou c'etait rouge dans mon post initial!

    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
    double* ConstruitParametres (int Dimension, int NbPoints, VecteurPtr Q[]) //Q contient NbPoints vecteurs de dimension Dimension
    {
    	int i;
    	double* t;
    	t[0]=0.;
    	for (i=1; i<NbPoints; i++)
    	{
    		t[i]=t[i-1]+DistancePoints(Q[i],Q[i-1]);
    		printf("Termine DistancePoints pour i=%d. t[%d]=%f\n",i,i,t[i]);
    	}
    	return t;
    }
    
    CourbeBezierPtr ConstruitCourbe (int Dimension, int NbPoints, int Degre, VecteurPtr Points[])
    {
    	if (NbPoints==Degre+1)
    	{
    		CourbeBezierPtr C = CourbeBezierConstructeur(Dimension, Degre);
    		printf("1/ C->Degre=%d\n",C->Degre); // vaut 2
    		MatricePtr M = MatriceConstructeur(NbPoints,C->Ordre);
    		printf("2/ C->Degre=%d\n",C->Degre); // vaut 2
    		double* A = ConstruitParametres(Dimension, NbPoints, Points);
    		int i,j,k;
    		printf("3/C->Degre=%d\n",C->Degre); // vaut 0 !!?
    		for (i=0; i<NbPoints; i++)
    		{
    			for (j=0; j<(C->Ordre); j++)
    			{
    				printf("A[%d]=%f, C->Degre=%d, j=%d\n",i,A[i],C->Degre,j);
    				M->Coef2d[i][j] = EvalueBernstein(C->Degre, j, A[i]);
    			}
    		}
    Priere de m'excuser pour cette erreur!

  8. #8
    Membre actif Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Points : 223
    Points
    223
    Par défaut
    Il faudrait donc que tu mettes sur ton post le code de la fonction ConstruitParametres et toutes les fonctions que celle-ci utilise
    Et une petite autre chose, dans la fonction "vecteurConstructeur" i ne sert à rien
    Et pour répondre à ta précédente question, je pense effectivement que tu fais un dépassement de tableau

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    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
    double* ConstruitParametres (int Dimension, int NbPoints, VecteurPtr Q[]) //Q contient NbPoints vecteurs de dimension Dimension
    {
    	int i;
    	double* t;
    	t[0]=0.;
    	for (i=1; i<NbPoints; i++)
    	{
    		t[i]=t[i-1]+DistancePoints(Q[i],Q[i-1]);
    		printf("Termine DistancePoints pour i=%d. t[%d]=%f\n",i,i,t[i]);
    	}
    	return t;
    }
     
    CourbeBezierPtr ConstruitCourbe (int Dimension, int NbPoints, int Degre, VecteurPtr Points[])
    {
    	if (NbPoints==Degre+1)
    	{
    		MatricePtr M = MatriceConstructeur(NbPoints,Degre+1);
    		double* A = ConstruitParametres(Dimension, NbPoints, Points);
    		int i,j,k;
    		CourbeBezierPtr C = CourbeBezierConstructeur(Dimension, Degre);
    		for (i=0; i<NbPoints; i++)
    		{
    			for (j=0; j<(C->Ordre); j++)
    			{
    				printf("A[%d]=%f, C->Degre=%d, j=%d\n",i,A[i],C->Degre,j);
    				M->Coef2d[i][j] = EvalueBernstein(C->Degre, j, A[i]);
    			}
    		}
    J'ai reussi a contourner le probleme en reformulant mon code comme ci-dessus en attendant votre reponse pour pouvoir continuer, mais il n'empeche que je ne suis vraiment pas convaincu de ce que fait le compilateur (pourtant ca m'arrive peu souvent). :-/

  10. #10
    Membre actif Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Points : 223
    Points
    223
    Par défaut
    L'erreur est là, vous déclarer t comme un double* puis vous accédez à t[i] comme si c'était un tableau de taille Nb_points alors que vous n'avez fait aucune allocation de mémoire préalable.
    Si je peux vous donner un conseil, faites confiance au compilateur, il ne fait que ce pour quoi il est prévu c'est à dire interprêter votre code.
    Il ne fait que ce que vous lui demandez de faire.

  11. #11
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    double* ConstruitParametres (int Dimension, int NbPoints, VecteurPtr Q[]) //Q contient NbPoints vecteurs de dimension Dimension
    {
    	int i;
    	double* t;
    	t[0]=0.;
    ....
    		t[i]=t[i-1]+DistancePoints(Q[i],Q[i-1]);
    .....
    	return t;
    }
    Il n'y a pas de mémoire allouée pour un tableau t de double, mais seulement pour un pointeur. Il manque un t = malloc(....);

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    Ah, pourtant j'ai tres souvent dans mon code essaye d'acceder a un indice de tableau sous forme de pointeur sans malloc et ca a toujours marche, sauf la. Curieux...

  13. #13
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Citation Envoyé par User Name Voir le message
    Ah, pourtant j'ai tres souvent dans mon code essaye d'acceder a un indice de tableau sous forme de pointeur sans malloc et ca a toujours marche, sauf la. Curieux...
    Non, ce n'est pas curieux. La question n'est pas l'accès aux éléments d'un tableau, mais l'existence du tableau.

    L'accès à un élément d'un tableau se fait toujours via l'adresse de l'élément, donc on comprend que l'utilisation de pointeurs soit fréquente pour ce faire.
    On peut citer pour les cas où la présence d'un (objet) pointeur s'impose :
    - celui de l'allocation dynamique
    - lorsqu'on on passe en argument d'une fonction un tableau, le paramètre de la fonction est un pointeur.
    - dans ce code : char const * p = "123456";
    - en C99 avec les objets anonymes.

    Mais dans tous les cas, il faut que le tableau existe, le pointeur ne stocke qu'une adresse. Et créer un pointeur ne crée pas de place pour l'objet pointé

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    348
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 348
    Points : 103
    Points
    103
    Par défaut
    Ok, je vais malloquer tous mes pointeurs, mais je garde quand meme ma solution, car je suis dans l'urgence.

    Merci a tous! ^^

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

Discussions similaires

  1. Compteur en sas qui ne fonctionne pas correctement
    Par huître dans le forum SAS Base
    Réponses: 10
    Dernier message: 09/05/2012, 17h28
  2. Application qui ne fonctionne pas correctement sur W7 64 bits
    Par JeanMarc_T2k dans le forum Windows 7
    Réponses: 6
    Dernier message: 22/03/2011, 12h34
  3. [CSS 2.1] Menu qui ne fonctionne pas correctement avec IE
    Par beegees dans le forum Mise en page CSS
    Réponses: 0
    Dernier message: 13/10/2010, 11h37
  4. Réponses: 2
    Dernier message: 02/01/2010, 13h52
  5. Un test if qui ne fonctionne pas correctement
    Par Shinjuku dans le forum Langage
    Réponses: 6
    Dernier message: 26/02/2008, 11h52

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