|
Dernière réponse | |
---|---|
Sujet : [C] Aux pros des pointeurs, Libération matrices | |
tgrx | 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...) |
Aperçu |
---|
Vue Rapide de la discussion |
---|
tgrx | 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...) |
BENB | tgrx > De toute facon il y a un moment ou il faut savoir s'arreter :D |
tgrx | 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: |
BENB |
|
tgrx | 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... :) |
tgrx |
|
BENB |
|
Pschitt | 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 @+ |
Pschitt | 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 |
BENB | 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] |
Pschitt | 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) |
tgrx | 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] |
BENB |
|
minusplus | non |
tgrx | :hello:
Tiens question bete : ca existe les inline en C ?? |
BENB |
|
tgrx |
|
BENB | 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] |
tgrx | 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; } |
Pschitt | 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 |
archangel | 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. |
tgrx | Voila la solution :
http://forum.hardware.fr/sqlforum/icones/icon14.gif |
minusplus | :lol: |
Pschitt | Voila 2 fonctions : |