Langage C: gestion de mémoire

Résolu/Fermé
viruk - 24 avril 2012 à 19:42
 viruk - 24 avril 2012 à 23:12
Bonjour,

j'ai rédigé un bout de programme que voici:

struct image {
int longueur;
int largeur;
int** mat;
};

typedef struct image* img;

img alloc(int a,int b) {
int** mat2= (int**)malloc(a*sizeof(int*));
int k;
for (k=0; k<a; k++){
mat2[k]=(int*)malloc(b*sizeof(int));
}
img mat1=(img)malloc(sizeof(struct image));
mat1->longueur=a;
mat1->largeur=b;
mat1->mat=mat2;
return mat1;
}


ce programme fonctionne il n'y a pas de problème, cependant je me pose une question:
lors du malloc pour libérer de la place pour le type img, combien de place il libère? vu qu'il ne connait pas la taille de la matrice...
et du coup si il libère suffisamment de place, est-ce qu'un free(mat2) ferait planter le programme?
merci pour votre réponse!

A voir également:

3 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
24 avril 2012 à 20:01
Attention, un malloc ne libère pas de la place. Il alloue de la place. S'il n'y a plus de place, il renvoie NULL. C'est free() qui libère la place.

Lors de ton malloc pour mat1, ton programme connaît la taille de ta structure : sizeof(int) + sizeof(int) + sizeof(int**) (j'omets volontairement les alignements mémoire). Le programme allouera bien une place de sizeof(int **) bytes dans la pile destinée à recevoir un pointeur sur un pointeur sur des entiers dans le heap. Dis autrement dans la pile, ta structure prend la taille d'une adresse mémoire. C'est en pointant vers cette adresse que tu retrouveras le contenu de ta structure.


free(mat2) ne te fera pas planter le programme. Il libérera juste l'allocation du pointeur mat2. Le problème est que tu ne pourras plus libérer les autres pointeurs mat2[k]. Il faut donc commencer par faire une boucle for de free(mat2[k]) et finir par free(mat2).

Cdlt,
1
ok
je te remercie d'avoir pris le temps de me répondre!
Viruk

après essai quand je fais les free et que je tente d'appeler alloc, ca me met une erreur de segmentation. Y'a-t-il un moyen d'éviter ca?
merci!
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
24 avril 2012 à 21:14
Tu as probablement fait une erreur. Merci de poster ton programme pour qu'on puisse t'aider.
Et n'oublies pas de mettre ton code entre des balises "code" (à droite du bouton souligné).
0
voici mon code.
et merci de m'avoir indique l'existence de ces balises =)

struct image {
int longueur;
 int largeur;
 int** mat;
};

typedef struct image* img;

img alloc(int a,int b) {
  int** mat2= (int**)malloc(a*sizeof(int*));	      	
  int k;					       
  for (k=0; k<a; k++){					
    mat2[k]=(int*)malloc(b*sizeof(int));
  }
  img mat1=(img)malloc(sizeof(struct image));
  mat1->longueur=a;
  mat1->largeur=b;
  mat1->mat=mat2;
  for(k=0;k<a;k++){
    free(mat2[k]);
  }
  free(mat2);
  return mat1;
}
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
24 avril 2012 à 22:12
On ne sait pas compris. Quand je disais d'utiliser free() c'est lorsuqe tu souhaites désallouer une zone que tu n'utiliseras plus.
Tu alloues mat2, puis mat1 et tu rattaches mat1->mat à mat2. C'est parfait. Seul problème, tu désalloues mat2, donc mat1.mat pointe sur une zone non allouée. Erreur de segmentation assurée si tu cherches à écrire dessus.
0
ok c'est ce qu'il me semblait.
du coup je ne peux le désallouer qu'après l'avoir utilisé dans le main si je comprends bien.
(j'utilise plusieurs fois cette fonction dans la suite de mon programme donc je pense que le free est nécessaire)
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
24 avril 2012 à 22:54
Effectievment, la désallocation est nécessaire. Mais faut pas le faire dans la fonction allocation, sinon cette dernière ne sert à rien. Il faut que tu te crées une fonction desalloc() qui prendra en argument ta structure img allouée.
Ensuite, niveau assemblage, tu appelles structure=alloc() dans le main() pour utiliser ta structure, et lorsque tu as fini de l'utiliser tu appelles desalloc(structure);
0
ok je vais faire ca!
merci!
0