[C] Aux pros des pointeurs, Libération matrices

Aux pros des pointeurs, Libération matrices [C] - Programmation

Marsh Posté le 14-06-2001 à 14:13:23    

Voila 2 fonctions :

Reply

Marsh Posté le 14-06-2001 à 14:13:23   

Reply

Marsh Posté le 14-06-2001 à 14:14:00    

:lol:

Reply

Marsh Posté le 14-06-2001 à 14:20:39    

Voila la solution :
 
http://forum.hardware.fr/sqlforum/icones/icon14.gif

Reply

Marsh Posté le 14-06-2001 à 14:24:07    

je suis désolé tgrx mais ta solution ne marche pas.
 
essaie plutôt ça:
 
http://forum.hardware.fr/sqlforum/icones/config.gif :gun:  
 
voilà le problème de Pschitt devrait être résolu.


---------------
J'suis timide - Prêt à mourir, mais pas à vivre - Je suis vraiement très fatigué ... - more than meets the eye
Reply

Marsh Posté le 14-06-2001 à 14:25:13    

Excusez moi pour ce dérapage de mulot
Donc je disais, voici 2 fonctions concernant les matrices 3D
 
      - 1 pour l'allocation qui fonctionne bien :
 
int * * * CreerMat3DEntier(int nbPlan, int nbLig, int nbCol)
{
 int * * * mat3D=NULL;
 int n,m;
 
 if(nbLig*nbCol*nbPlan==0)  
   
  return(int * * *)NULL;
 
 mat3D=(int * * *) malloc (nbPlan*sizeof(int * *));
 
 if(!mat3D)  
   
  return (int * * *)NULL;
 
 for(n=0;n<nbPlan;n++)
 
 {mat3D[n]=(int * *) malloc (nbLig*sizeof(int*));
 
  if(mat3D==NULL)
 
  return (int * * *)NULL;
   
 mat3D[n][0]=(int*) malloc (nbLig*nbCol*sizeof(int));  
 
 for(m=0;m<nbLig;m++)
 
   mat3D[n][m] = mat3D[n][0] + m*nbCol;
 }
 
 return(mat3D);
}
 
      - 1 pour la libération mémoire qui foire ?:
 
int LibererMat3DEntier(int * * * * mat3D, int nbPlan)  
{
 int k;
 
 for(k=0;k<nbPlan;k++)
   
 {free(* mat3D[k][0]);    
  free(* mat3D[k]);      
 }
 
 free(* mat3D);
 
 return((int)* mat3D);
}
 
Si j'alloue une matrice de taille CreerMat3DEntier(2,2,2), lors de la libération :
Au premier passage de la boucle : Tout baigne  
Au deuxième   "           "     (Pour le 2ème plan): Plantage ??
J'ai déja essayé pas mal de modifs mais rien à faire, ça plante inexorablement.
 
Si quelqu'un a une idée ?
 
Merci

Reply

Marsh Posté le 14-06-2001 à 14:31:08    

Ouh la, c'est un peu le foutoir ton truc... a ta place j'ecrirais un truc comme ca :
 
int* matrix= malloc(nbPlan*nbLig*nbCol*sizeof(int));
comme ca tu desalloue en faisant un bete :
free(matrix);
 
et tu implementes les fonctions suivant pour acceder aux elements de ta matrice :
 
int getValue(int* matrix, int i, int j, int k)
{
  return matrix[(k*nbCol+j)*nbLig+i];
}
 
void setValue(int* matrix, int i, int j, int k, int val)
{
  matrix[(k*nbCol+j)*nbLig+i]= val;
}

Reply

Marsh Posté le 14-06-2001 à 14:35:18    

Le conseil du jour ***
J'aurais contourne le pb en creant une classe Matrice et en l'allouant d'un bloc.
marche bien pour des petites matrices (2,2,2) dans ton exemple.
 
------
La reponse ***
sinon pourquoi l'etoile dans les free ?
 
int LibererMat3DEntier(int * * * * mat3D, int nbPlan)  
{  
int k;  
 
for(k=0;k<nbPlan;k++)  
   
{free( mat3D[k][0]);    
  free( mat3D[k]);      
}  
 
free( mat3D);  
   
return((int)* mat3D);  
}  
 
----
La remarque ***
Lors de l'allocation commences ta boucle a 1
 
mat3D[n][0]=(int*) malloc (nbLig*nbCol*sizeof(int));  
   
for(m=1;m< nbLig;m++) // <------ ICI
 
   mat3D[n][m] = mat3D[n][0] + m*nbCol;  
 
en effet le cas 0 est resolu par la ligne precedente
 
(oui je sais ca ne change rien, mais bon...)
 
----
Bon tgrx m'a grillee, zut...

 

[edit]--Message édité par BENB--[/edit]

Reply

Marsh Posté le 14-06-2001 à 14:36:47    

BENB a écrit a écrit :

Le conseil du jour ***
J'aurais contourne le pb en creant une classe Matrice et en l'allouant d'un bloc.
marche bien pour des petites matrices (2,2,2) dans ton exemple.




 
Tout a fait d'accord, mais la c'est du C, pas du C++

Reply

Marsh Posté le 14-06-2001 à 14:43:41    

tgrx a écrit a écrit :

 
 
Tout a fait d'accord, mais la c'est du C, pas du C++




j'ai realise apres avoir mis le conseil...
puis j'ai vu que tu donnais le meme conseil, mais en C alors j'ai laisse...
Simplement les fonctions d'acces il vaut mieux les faire en macros sinon ca va rammer, et comme je hais les macros... retour au C++...
 
Mais TU AS RAISON ! mea culpa !

Reply

Marsh Posté le 14-06-2001 à 14:45:36    

:hello:
 
Tiens question bete : ca existe les inline en C ??

Reply

Marsh Posté le 14-06-2001 à 14:45:36   

Reply

Marsh Posté le 14-06-2001 à 14:52:36    

non

Reply

Marsh Posté le 14-06-2001 à 14:52:48    

tgrx a écrit a écrit :

:hello:
 
Tiens question bete : ca existe les inline en C ??




Pas a ma connaissance...
Maintenant il n'y a pas beaucoup de compilos C, donc je pense que l'implementation C des compilos C++ gere les inlines...
mais sinon il n'y a que les macros (C ansi88)

Reply

Marsh Posté le 14-06-2001 à 15:07:31    

Mince, il faut donc faire un truc du style :
 
typedef struct
{
/* dimensions de la matrice */
  int I;  
  int J;
  int K;
/* valeurs */
  int * values;
}
Matrix;
 
#define MATRIX(m,i,j,k) m.values[(k*m.J+j)*m.I+i]
 
 
 
et donc ensuite ca roule :
 
Matrix m;
m.i= 2;
m.j= 2;
m.k= 2;
m.values= malloc(2*2*2*sizeof(int));
 
pour ecrire une valeur :
MATRIX(m,0,1,0)= 5;
 
pour lire une valeur :
printf("%d\n", MATRIX(m,0,1,0));
 
et enfin liberer la matrice :
free(m.values);

 

[edit]--Message édité par tgrx--[/edit]

Reply

Marsh Posté le 14-06-2001 à 15:11:34    

Mon pb est zarbie,
 
ça plante sous VC++ mais ça tourne sur TurboC ?? Va comprendre
 
BENB,  
 
la raison de l'étoile dans les free est que je passe à la fonction l'adresse de la matrice, LibererMat3DEntier(&mat3D,2)  
pour que mat3D soit mis à NULL dans la fonction appelante.    
Pour éviter que l'utilisateur n'y comprenne rien ou éviter qu'il oublie de passer l'adresse, 1 macro s'impose :
#define LibererMat3DEntier(x,y) LibererMat3DEntier(&x,y)

Reply

Marsh Posté le 14-06-2001 à 15:24:19    

Les compilos Borland sont reputes etre plus permissifs que les compilo Macrosoft :D...
 
vi j'avais confondus le int **** mat3d avec un int *** mat3d, honte a moi... (j'avais jamais ete jusqu'au **** il faut oser :D)
 
quel sont les priorites de * et de [] ?
il ne faudrait pas faire (*mat3D)[k][0] plutot que * mat3d[k][0] ?  
Je me trompe peut-etre mais pour moi * mat3d[k][0] ce developpe en
*( *(mat3d+k)+0) alors que tu veux (*(*mat3d)+k)+0
 
J'aime pas les macros, mais en plus quand il y a le meme identifiant a dte et a gche, alors je prend peur !

 

[edit]--Message édité par BENB--[/edit]

Reply

Marsh Posté le 14-06-2001 à 17:37:38    

BENB je pense que tu as vu juste, mon problème vient probablement de cette expression : * mat3D[k][0] qui devrait plutôt être (*mat)[k][0], je n'ai pas VC++ au boulot mais je vais essayer ce soir.
Par contre ça n'explique pas que les 2 free(...) du 1er passage(1er PLan) fonctionnent :(
 
Quant à ma macro, c'est clair qui il est préférable d'écrire :
quelque chose dans ce genre :
#define LibererMat3D(x,y) _libererMat3D(&x,y)
 
Mais tout ça n'est pour moi qu'au stade expérimental pour l'instant.  
 
Merci de votre aide

Reply

Marsh Posté le 14-06-2001 à 19:59:44    

Je confirme que le problème venait bien des ces expressions :
 
* mat3D[k][0] -> (* mat3D)[k][0]  
* mat3D[k]    -> (* mat3D)[k]      
 
Merci à toi O grand BENB
 
Sinon y paraît que si la matrice a été allouée de façon consécutive en mémoire, on peut optimiser sa libération par :
 
for(k=0;k<nbLig*nbCol;k++)
 
      (* mat + k) = 0;
 
Mais y'en a pas avoir testé
 
Merci  
 
@+

Reply

Marsh Posté le 15-06-2001 à 10:22:05    

Pschitt a écrit a écrit :

Je confirme que le problème venait bien des ces expressions :
 
* mat3D[k][0] -> (* mat3D)[k][0]  
* mat3D[k]    -> (* mat3D)[k]      
 
Merci à toi O grand BENB
 
Sinon y paraît que si la matrice a été allouée de façon consécutive en mémoire, on peut optimiser sa libération par :
 
for(k=0;k<nbLig*nbCol;k++)
 
      (* mat + k) = 0;
 
Mais y'en a pas avoir testé
 
Merci  
 
@+




Merci...  meme si je ne suis pas si grande que cela :D
Que veux tu dire ?
pour chaque malloc tu dois avoir un free...
 
evidement tu peux faire comme le dis tgrx un seul malloc d'ou un seul free...
 
le pb de cette technique est la disponibilite d'une zone memoire de la taille indiquee. La memoire a tendence a se fragmenter tu as plus de chances de touver beaucoup de petites zones plutot qu'une grande... cette technique (celle de tgrx) est donc parfaite si tes matrices sont petites. Ensuite a toi de choisir si tu utilise la technique du calcul de decalage (tgrx) ou de precalculer les adresses comme tu le fais une fois l'allocation des plans faite.

Reply

Marsh Posté le 15-06-2001 à 10:24:07    

BENB a écrit a écrit :

 
evidement tu peux faire comme le dis tgrx un seul malloc d'ou un seul free...
le pb de cette technique est la disponibilite d'une zone memoire de la taille indiquee. La memoire a tendence a se fragmenter tu as plus de chances de touver beaucoup de petites zones plutot qu'une grande... cette technique (celle de tgrx) est donc parfaite si tes matrices sont petites. Ensuite a toi de choisir si tu utilise la technique du calcul de decalage (tgrx) ou de precalculer les adresses comme tu le fais une fois l'allocation des plans faite.




 
de toute facon il s'en fout de mes indications... :cry:

Reply

Marsh Posté le 15-06-2001 à 10:29:38    

D'ailleurs une remarque au niveau performance, lorsque l'on fait tableau[a][b][c], le compilateur ne fait rien d'autre que de reindexer a,b,c dans le grand tableau que constitue de la RAM.
 
Donc au final, c'est la meme chose de le faire dans le programme ou de laisser faire le compilo... et en plus comme le souligne BENB tout allouer d'un bloc evite la fragmentation... :)

Reply

Marsh Posté le 15-06-2001 à 10:30:01    

tgrx a écrit a écrit :

 
 
de toute facon il s'en fout de mes indications... :cry:




Allons ne pleure pas ...
 
mais non il ne s'en fout pas la preuve il commence a s'y interesser...
 
A propos comment sont les bords de ton maillage ?

Reply

Marsh Posté le 15-06-2001 à 10:35:57    

Tes idees etaient tres bonnes pour les conditions aux frontieres, mais... dans un de mes fichiers a traiter j'ai quelque chose comme 82 variables http://forum.hardware.fr/sqlforum/icones/icon16.gif... donc je vais pas m'amuser a ecrire des formules censees extrapoler ces valeurs (ces formules peuvent varier avec les fichiers en plus...) :sarcastic:
 
Donc pour faire mon interpolation aux frontieres, ben je la fais pas sur 8 valeurs, mais sur moins que 8 (en fait j'elimine les points de la frontiere), et en fait ca marche pas trop mal... donc bon... :benetton:

Reply

Marsh Posté le 15-06-2001 à 11:29:20    

tgrx > De toute facon il y a un moment ou il faut savoir s'arreter :D

Reply

Marsh Posté le 15-06-2001 à 11:32:05    

BENB> oui exactement ;) et puis de toute facon mon stage se finit dans 2 semaines exactement, ca me laisse tout juste le temps de boucler tout le bazar et de taper le sempiternel rapport (ca c pas cool :( j'ai horreur de passer des heures a ecrire des choses que je sais deja...)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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