Pointeurs et Desallocation

Signaler
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004
-
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004
-
Bonjour à tous....

je declare une fonction

loadJpegImage(char *, unsigned char*, int*, int*)

1e parametre : le chemin de l'image chargee
2e // : le tableau (ou pointeur sur char) contenant l'image en question
3e et 4e // : les hauteur et largeur de l'image qui vont conditionner les dimensions du tableau dynamique
cette fonction est appelee dans le main :

unsigned char *text;
int height, width;
loadJpegImage(chemin, text, &width, &height);

dans le corps de la fonction,
la dimension de text est allouee dynamiquement :

int loadJpegImage(char *fichier, unsigned char *texture, int *Pt_width, int *Pt_height)
{
....
....
....

texture = (unsigned char *)malloc(dim_gris*sizeof(unsigned char));

....
....
....
}

Le souci intervient lorsque je souhaite :

1 - mapper mon objet => aucun mappage n'est effectue comme si le tableau etait vide
2 - desallouer la memoire => erreur a la compilation "Freeing inexistant memory"
Ces deux actions sont faites au sein du main.

Merci pour vos remarques et/ou suggestions.

6 réponses

Messages postés
321
Date d'inscription
dimanche 22 octobre 2000
Statut
Membre
Dernière intervention
14 mai 2005
2
C'est très simple...

loadJpegImage(char *, unsigned char**, int*, int*)

////////////////////////////////////////////////////
Dans le main :

unsigned char *text;
int height, width;
loadJpegImage(chemin, &text, &width, &height);

////////////////////////////////////////////////////
int loadJpegImage(char *fichier, unsigned char **texture, int *Pt_width, int *Pt_height)
{
....
....
....

*texture = (unsigned char *)malloc(dim_gris*sizeof(unsigned char));

....
....
....
}

Voilà, la ça marchera bien...

Tu faisais une allocation dynamique (avec malloc) à l'interieur de ta fonction. Tu dois donc passé le pointeur (unsigned char *) par adresse afain que la valeur de 4 octets qu'il vaudra (retrourné par malloc) soit bien pris en compte à la sortie de ta fonction.

Quand tu alloues ou désalloues à l'interieur d'une fonction un pointeur, il faut toujours le passer en parmètre par adresse (par exemple char **).
C'est une règle simple... et qui marche à tout les coup....

Prend le temps de bien réfléchir et tu comprendras le mécanisme...

Sinon, j'essaierais d'être plus clair...

++
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
evitez le cast du malloc en c, c'est de toute facon inutile
Messages postés
321
Date d'inscription
dimanche 22 octobre 2000
Statut
Membre
Dernière intervention
14 mai 2005
2
malloc retourne un void *.

Donc, certain compilateur ne voudront pas compiler si tu ne cast pas le pointeur retourné par le malloc.

Donc, au contraire, le cast est justemen très utile et devrait être fait dans ous les cas pour éviter tout problème lié au compilo.
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
c'est justement parce que ca retourne un void* que le cast n'est pas necessaire

a quoi sert le type void* en c ?

"certain compilateur ne voudront pas compiler si tu ne cast pas le pointeur retourné par le malloc"

un compilateur c++ oui, mais pas un compilateur c
et on avais deja dis pourquoi ca pouvais etre dangereux en c le cast d'une valeur retour, tu cache au compilateur le type retour (qui sera int par defaut) dans le cas ou il genere lui meme la declaration (declaration implicite)

le cast du malloc + l'oubli d'inclure stdlib.h est la pire des erreurs
Messages postés
321
Date d'inscription
dimanche 22 octobre 2000
Statut
Membre
Dernière intervention
14 mai 2005
2
Désolé, c'est vrai que je parlais d'un compilateur C++.

Autant pour moi...
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004

Bon... Si quelqu'un y comprend qq chose....
Avec le passage par adresse, je n'avais plus d'erreur de memoire.
Mais le mappage, c'était pas vraiment ça, meme completement absent pour tout dire.
Je suis revenu a quelque chose de basique :

un pointeur simple sur unsigned char pour ma variable texture qui contient les pixels de mon image. Histoire d'avoir les idees un peu plus claires.

du coup plus d'erreur de desallocation, mais pas plus de mappage que precedemment.

Je vous livre le code. J'espere que qq un aura la synthese qu'il m'a manque.

Merci....

///////////////////// MAIN ////////////////////////

int main(int argc, char **argv)
{
unsigned char *text;
....
....

/* Chargement de la texture */

text=loadJpegImage(chemin, &width, &height);
....
....

gluBuild2DMipmaps(GL_TEXTURE_2D,3,width,height,GL_RGB,GL_UNSIGNED_BYTE,text);
....
....
}

///////////////////// IMAGE ////////////////////////

unsigned char *loadJpegImage(char *fichier, int *Pt_width, int *Pt_height)
{
....
....

unsigned char *ligne;
FILE *file;

int t_width = cinfo.image_width;
int t_height = cinfo.image_height;

Pt_width = &(t_width);
Pt_height = &(t_height);

if (cinfo.jpeg_color_space==JCS_GRAYSCALE)
{
int dim_gris = (t_width * t_height);

unsigned char *image_gris = (unsigned char
*)malloc(dim_gris*sizeof(unsigned char));
if (image_gris == NULL){cout<<endl<<"Erreur d'allocation
image_gris"<<endl;exit(0);}

unsigned char *texture = (unsigned char
*)malloc(dim_gris*3*sizeof(unsigned char));
if (texture == NULL){cout<<endl<<"Erreur d'allocation
texture"<<endl;exit(0);}

#ifdef PERFORM_MEMORY_CHEKS
MEMCHEK_reportLeak();
#endif

jpeg_start_decompress(&cinfo);
ligne=image_gris;

while (cinfo.output_scanline<cinfo.output_height)
{
ligne=image_gris+t_width*cinfo.output_scanline;
jpeg_read_scanlines(&cinfo,&ligne,1);
}

jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);

// rearrangement de l'image scannee dans le tableau de texture 3D
// ici nous sommes en niveau de gris, donc on copie le meme octet dans
// chacune des 3 cases RGB

for (i=0;i<t_height;i++)
for (j=0;j<t_width;j++)
{
texture[i*t_width*3+j*3 ] = image_gris[i*t_width+j];
texture[i*t_width*3+j*3+1] = image_gris[i*t_width+j];
texture[i*t_width*3+j*3+2] = image_gris[i*t_width+j];
}

free(image_gris);

return texture;
}
}