[C] problème de pointeur

problème de pointeur [C] - C - Programmation

Marsh Posté le 29-04-2004 à 17:29:51    

Bonjour,
 
Voici le code interressant:
 

Code :
  1. typedef struct
  2. {
  3.   float x;
  4.   float y;
  5. } fPoint;
  6. int main( int argc, char **argv, char **env )
  7. {
  8. static fPoint *tabCentre, **tabSouris;
  9.   AllocTab( &tabCentre, &tabSouris );
  10. return( 0 );
  11. }
  12. int AllocTab( fPoint **pTabCentre, fPoint ***pTabSouris )
  13. {
  14. int i, nbMotif, nbSouris;
  15.     *pTabSouris = (fPoint **)malloc( nbMotif * sizeof( fPoint * ) );
  16.     for( i = 0; i < *pNbMotif; i++ )
  17.       (*pTabSouris)[i] = (fPoint *)malloc( nbSouris * sizeof( fPoint ) );
  18.     *pTabCentre = (fPoint *)malloc( nbMotif * sizeof( fPoint ) );
  19.     Reflexion( nbMotif, pTabCentre );
  20. return( 0 );
  21. }
  22. void Reflexion( int nbMotif, fPoint **pTabCentre )
  23. {
  24. fPoint centre;
  25.     switch( nbMotif )
  26.     {
  27.       case 1:
  28.         pTabCentre[0]->x = centre.x;
  29.         pTabCentre[0]->y = centre.y;
  30.       break;
  31.       case 2:
  32.         pTabCentre[0]->x = centre.x;
  33.         pTabCentre[0]->y = centre.y - taille;
  34. // pTabSouris OK
  35.         pTabCentre[1]->x = centre.x;
  36. // pTabSouris a changer
  37.         pTabCentre[1]->y = centre.y + taille;
  38.       break;
  39.   }
  40. return;
  41. }


 
J'ai simplifier au maximum. Dans un premier temps, j'appelle la fonction avec nbMotif égal à 1: tout va bien mais losque je recommence (je désallou tout auparavant) avec nbMotif égale à 2, sa segfault!
J'ai réussi a voir que l'adresse de *pTabSouris[0] a changer juste aprés TabCentre[1]->x = centre.x.
 
Je pense qu'il y a un problème d'écrasement mais je ne vois pas où!
 
Merci de votre aide

Reply

Marsh Posté le 29-04-2004 à 17:29:51   

Reply

Marsh Posté le 29-04-2004 à 17:36:33    

http://www.eurorscg-ensemble.com/img/etoiles.gif


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 29-04-2004 à 17:51:59    

As-tu bien fait une analyse avant de taper ton code ?
Algo, pseudo-code...

Reply

Marsh Posté le 29-04-2004 à 17:59:21    

christophe_d13 a écrit :

As-tu bien fait une analyse avant de taper ton code ?
Algo, pseudo-code...


Oui c'est fait. Si c'est mal organiser c'est juste que j'ai extrait 20 lignes sur quelque 1000 lignes.

Reply

Marsh Posté le 29-04-2004 à 18:25:53    

Dans reflexion, il faut écrire  
 (*pTabCentre)[1].x
eu lieu
 pTabCentre[1]->x
 
Edit : en fait tu avais du pot avec nbMotif==0 car (*pTabCentre)[0].x est "équivalent" à pTabCentre[0]->x.  
pTabCentre, c'est le pointeur sur le tableau  donc pTabCentre[1] désigne l'@ mémoire juste après le pointeur qui dans ton cas  devait être pTabSouris et c'est pour ça qu'il était modifié...
 
 
 
ou alors, comme tu ne modifie pas pTabCentre, tu définie  Reflexion comme :
void Reflexion( int nbMotif, fPoint *pTabCentre )
dedans, tu utilises des    
 pTabCentre[0].x
 
et tu appelles  
Reflexion( nbMotif, *pTabCentre );
 
 
 
Ce bout de code me rappelle mes débuts en C [:meganne]  
Essayes quand même de limiter au maximum les truc du genre ***, c'est pas gérable en fait.
Par exemple écrit une fonction pour allouer tabSouris une autre pour  
tabCentre.
 
Ton main deviendrait :
 static fPoint *tabCentre, **tabSouris;  
 tabClentre = alloueTabCentre();
 tabSouris = alloueTabSouris();
 Reflexion( nbMotif, tabSouris );


Message édité par pascal_ le 29-04-2004 à 18:30:34
Reply

Marsh Posté le 29-04-2004 à 18:33:07    

cherche pas regarde ta fonction alloc et regarde la valeur de tes variables :o


---------------
«Le succès consiste à aller d'échecs en échecs sans jamais perdre son enthousiasme» - Churchill
Reply

Marsh Posté le 29-04-2004 à 18:45:35    

fFluFf a écrit :

cherche pas regarde ta fonction alloc et regarde la valeur de tes variables :o


 :??: ça a l'air d'être bon, non ?

Reply

Marsh Posté le 29-04-2004 à 19:19:37    

Code :
  1. int AllocTab( fPoint **pTabCentre, fPoint ***pTabSouris )
  2.   {
  3.     int i, nbMotif, nbSouris;
  4.         *pTabSouris = (fPoint **)malloc( nbMotif * sizeof( fPoint * ) );
  5.         for( i = 0; i < *pNbMotif; i++ )
  6.           (*pTabSouris)[i] = (fPoint *)malloc( nbSouris * sizeof( fPoint ) );
  7.         *pTabCentre = (fPoint *)malloc( nbMotif * sizeof( fPoint ) );
  8.         Reflexion( nbMotif, pTabCentre );
  9.     return( 0 );
  10.   }


Question : quel est la valeur de nbMotif
 
Autre question :

Code :
  1. Quel est la différence entre
  2. (*pTabCentre)[1].x
  3. pTabCentre[1]->x


réponse aucune ;)


Message édité par ffluff le 29-04-2004 à 19:19:54

---------------
«Le succès consiste à aller d'échecs en échecs sans jamais perdre son enthousiasme» - Churchill
Reply

Marsh Posté le 29-04-2004 à 19:22:53    

fFluFf a écrit :


Question : quel est la valeur de nbMotif
 
c'est du code simplifié :o, il n'y a pas tout
 
Autre question :

Code :
  1. Quel est la différence entre
  2. (*pTabCentre)[1].x
  3. pTabCentre[1]->x


réponse aucune ;)
 
mais si
 

Reply

Marsh Posté le 29-04-2004 à 19:39:13    

du code simplifié :
Comment tu veux qu'on lui dise ou est l'erreur si il donne pas tout. Pour moi c'est pas du code simplifié.
 
ah bon et c'est quoi la différence ?
dans pTabCentre[1]->x :
pTabCentre[1] est un pointeur donc on accede à son attribut avec une "->"
(*pTabCentre[1]) est un objet (pas un pointeur) donc on accède à son attribut avec un "."
 
donc si je comprends bien pour toi
fpoint *p = malloc(sizeof(fpoint));
p->x = 3; et  
(*p).x = 3
sont différent ?


---------------
«Le succès consiste à aller d'échecs en échecs sans jamais perdre son enthousiasme» - Churchill
Reply

Marsh Posté le 29-04-2004 à 19:39:13   

Reply

Marsh Posté le 30-04-2004 à 09:33:58    

fFluFf a écrit :

du code simplifié :
Comment tu veux qu'on lui dise ou est l'erreur si il donne pas tout. Pour moi c'est pas du code simplifié.


 
:ange: il a écrit que c'était simplifié et il donne juste les lignes de son programme qui foirent + allocation de ses tableaux.
 
 

fFluFf a écrit :


ah bon et c'est quoi la différence ?
dans pTabCentre[1]->x :
pTabCentre[1] est un pointeur donc on accede à son attribut avec une "->"
(*pTabCentre[1]) est un objet (pas un pointeur) donc on accède à son attribut avec un "."

 
 
Je crois que tu n'as pas bien lu sa fonction.  Si je schématise, on a ça :
 

Code :
  1. ...
  2.   fPoint *pTabCentre = malloc( ... );
  3.   Reflexion( & pTablCentre ); // il passe un pointeur sur le pointeur
  4.   ...
  5. Reflexion( fPoint **pTableCentre ){
  6.   pTabCentre[1]->x = 0;
  7.   /* Plantage :
  8.      On a :
  9.       **pTableCentre  =====> *pTableCentre =====>  |---------|
  10.                                                    |   4     |
  11.                                                    |---------|
  12.                                                    |   78    |
  13.                                                    |---------|
  14.                                                    |   87    |
  15.                                                    |---------|
  16.                                                    |   12    |
  17.                                                    |---------|
  18.                                                    |   48    |
  19.                                                    |---------|
  20.     pTableCentre[1] désigne la case mémoire qui suit *pTableCentre :
  21.      pTableCentre[1] ==      *pTableCentre =====>  |---------|
  22.                       |                            |   4     |
  23.                       |===>   Indéfini             |---------|
  24.                                                    |   78    |
  25.                                                    |---------|
  26.                                                    |   87    |
  27.                                                    |---------|
  28.                                                    |   12    |
  29.                                                    |---------|
  30.                                                    |   48    |
  31.                                                    |---------|
  32.    La différence entre  (*pTabCentre)[1].x  et  pTabCentre[1]->x est que
  33.       pTabCentre[1]->x sous-entends que pTabCentre est un pointeur sur un tableau
  34.       dans (*pTabCentre)[1].x pTabCentre est bien un pointeur sur un pointeur de tableau
  35.   */
  36.    /* En fait il fait ça pour simplifier encore : */
  37.    ....
  38.    int i;
  39.    Reflexion( &i );
  40.    ...
  41.    Reflexion( int *i ){
  42.      i[1] = 45;
  43.    }
  44. }


 
J'espère que mes explications ne sont pas trop :pt1cable:
 
 

fFluFf a écrit :


donc si je comprends bien pour toi
fpoint *p = malloc(sizeof(fpoint));
p->x = 3; et  
(*p).x = 3
sont différent ?

 
Ben non identiques et il n'y a pas de contradiction...
 

Reply

Marsh Posté le 30-04-2004 à 15:54:11    

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct
  4. {
  5.   float x;
  6.   float y;
  7. } fPoint;
  8. int AllocTab( fPoint ***pTabSouris )
  9. {
  10.     int i, nbSouris=3;
  11.     *pTabSouris = malloc( nbSouris * sizeof( fPoint * ) );
  12.     for( i = 0; i < nbSouris; i++ )
  13.       (*pTabSouris)[i] = malloc( nbSouris * sizeof( fPoint ) );
  14.     return( 0 );
  15. }
  16. int main()
  17. {
  18.   fPoint **tab;
  19.   AllocTab(&tab);
  20.   fPoint pt1={1.0, 3.0};
  21.   fPoint pt2={20.0, 40.0};
  22.   tab[0]=&pt1;
  23.   tab[1]=&pt2;
  24.   tab[2]->x = tab[2]->y = -1;
  25.   printf("tab[i]->j\n" );
  26.   printf("%f %f\n", tab[0]->x, tab[0]->y);
  27.   printf("%f %f\n", tab[1]->x, tab[1]->y);
  28.   printf("%f %f\n", tab[2]->x, tab[2]->y);
  29.   printf("(*tab[i]).j\n" );
  30.   printf("%f %f\n",(*tab[0]).x, (*tab[0]).y);
  31.   printf("%f %f\n",(*tab[1]).x, (*tab[1]).y);
  32.   printf("%f %f\n",(*tab[2]).x, (*tab[2]).y);   
  33.   tab[0]->x = 15.0;
  34.   tab[1]->x = 12.0;
  35.   tab[2]->y = 17.0;
  36.   printf("\ntab[i]->j\n" );
  37.   printf("%f %f\n", tab[0]->x, tab[0]->y);
  38.   printf("%f %f\n", tab[1]->x, tab[1]->y);
  39.   printf("%f %f\n", tab[2]->x, tab[2]->y);
  40.   printf("(*tab[i]).j\n" );
  41.   printf("%f %f\n",(*tab[0]).x, (*tab[0]).y);
  42.   printf("%f %f\n",(*tab[1]).x, (*tab[1]).y);
  43.   printf("%f %f\n",(*tab[2]).x, (*tab[2]).y);   
  44.   return 0;
  45. }


 

Code :
  1. <15:50:36>.oO( fluf@XeoN~/Etudes/C_C++/taiste )Oo.
  2. $ gcc pointeur.c -Wall -ansi -std=c99 && ./a.out
  3. tab[i]->j
  4. 1.000000 3.000000
  5. 20.000000 40.000000
  6. -1.000000 -1.000000
  7. (*tab[i]).j
  8. 1.000000 3.000000
  9. 20.000000 40.000000
  10. -1.000000 -1.000000
  11. tab[i]->j
  12. 15.000000 3.000000
  13. 12.000000 40.000000
  14. -1.000000 17.000000
  15. (*tab[i]).j
  16. 15.000000 3.000000
  17. 12.000000 40.000000
  18. -1.000000 17.000000


no comment.
 
Cependant pendant l'écriture de ce programme j'ai rencontré quels "trucs" bizard :

Code :
  1. *pTabSouris = (fPoint **)malloc( nbMotif * sizeof( fPoint * ) ); // ca serais pas plustot nbSouris ?
  2.         for( i = 0; i < *pNbMotif; i++ ) // *pnbMotif ?? pourquoi pas nbMotif ou nbSouris ?
  3.           (*pTabSouris)[i] = (fPoint *)malloc( nbSouris * sizeof( fPoint ) );


 
je n'ai rien changé à l'algo sauf que j'ai enlevé :
- la création de pTabCentre  
- enlevé nbMotif  
- remplacé nbMotifpar nbSouris  
- (et bien sur enlevé les casts inutiles)


---------------
«Le succès consiste à aller d'échecs en échecs sans jamais perdre son enthousiasme» - Churchill
Reply

Marsh Posté le 30-04-2004 à 16:33:37    

Je crois que tu n'as toujours lu pas sa fonction.
Tu fais ça :


                  |---------|        
**fPoint  =====>  |   @     | ===> {1.0, 3.0};
                  |---------|        
                  |   @+1   | ===> {20.0, 40.0};
                  |---------|        
                  |   @+2   | ===> {-1.0, -1.0];  
                  |---------|        
 


 
au lieu de ça :
 


      **pTableCentre  =====> *pTableCentre =====>  |---------|
                                                   |   4     |
                                                   |---------|
                                                   |   78    |
                                                   |---------|
                                                   |   87    |
                                                   |---------|
                                                   |   12    |
                                                   |---------|
                                                   |   48    |
                                                   |---------|


 
Un exemple :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct{
  4.     int x;
  5. }Toto;
  6. void test( Toto **ptab ){
  7.     printf( "%d \n", (*ptab)[1].x   ); // ok
  8.     printf( "%d \n",  ptab[1]->x    ); // pas ok ou plantage
  9. }
  10. int main(int argc, char *argv[])
  11. {
  12.   Toto *pTab = (Toto*) malloc( sizeof(Toto)*3 );
  13.  
  14.   pTab[0].x=pTab[1].x=pTab[2].x=2004;
  15.  
  16.   test( &pTab );
  17.  
  18.   system("PAUSE" );
  19.   return 0;
  20. }


 
Et j'ai jamais dis que  tab[0]->y était différent de (*tab[0]).y (comme tu sembles le suggérer avec ton exemple)  
mais que  (*tab)[1].x est différent de tab[1]->x
 

Reply

Marsh Posté le 30-04-2004 à 18:32:43    

Autant pour moi j'ai cru depuis le début qu'il appelé reflexion sur ptabSouris et non ptabCentre.
 
 
encore désolé mais ca n'explique pas le :
for( i = 0; i < *pNbMotif; i++ ) ...


---------------
«Le succès consiste à aller d'échecs en échecs sans jamais perdre son enthousiasme» - Churchill
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed