[C/C++] Malloc et occupation mémoire sous Win2000

Malloc et occupation mémoire sous Win2000 [C/C++] - C++ - Programmation

Marsh Posté le 09-04-2003 à 16:09:46    

Voilà, j'ai trouvé ce bout de code sur le net :

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. /**
  5. * fonction qui accepte une chaine en entrée
  6. * qui ajoute à cette chaine la string ".cpp" et qui la
  7. * renvoie
  8. */
  9. char* extensionCPP(char *nomFichier)
  10. {
  11.     //buffer qui va contenir la chaine en entier
  12.     char buffer;
  13.    //allouer un espace mémoire suffisant pour accepter la chaine  
  14.    //+ l'extension .cpp
  15.    buffer = (char *)malloc(strlen(nomFichier)+4+1);
  16.    //copier le nom de fichier
  17.    strcpy(buffer, nomFichier);
  18.    //ajouter l'extension
  19.    strcat(buffer, ".cpp" );
  20.     //renvoyer la nouvelle chaine
  21.     return buffer;
  22. }


 
OK, mais un truc me chagrine : comment va-t-on faire pour libérer l'espace mémoire pointé par buffer (alloué par malloc) ?
Pourra-t-on faire un free() de ce pointeur dans un autre fonction ? car là je me dis qu'après plusieurs appels à extensionCPP(), l'occupation mémoire va gonfler, non ?

Reply

Marsh Posté le 09-04-2003 à 16:09:46   

Reply

Marsh Posté le 09-04-2003 à 16:11:16    

c'est la fonction appelante qui va devoir libérer la mémoire je suppose... et à part un free du pointeur renvoyer je vois pas vraiment d'autre solution :D


Message édité par antp le 09-04-2003 à 16:11:40

---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 09-04-2003 à 16:12:24    

quand tu appelle ta fonction par :

Code :
  1. szPipo=extensionCPP("blablabla" );


 
ton pointeur alloué est renvoyé dans la variable szPipo
donc un petit  

Code :
  1. if (szPipo) free(szPipo)


 
et hop :D

Reply

Marsh Posté le 09-04-2003 à 16:12:31    

vi, un pointeur alloue (enfin la memoire sur laquelle il pointe) par malloc peut etre liberé par malloc dans n'importe quel autre endroit du prog (enfin, sauf dll mais passons).
 

Citation :

car là je me dis qu'après plusieurs appels à extensionCPP(), l'occupation mémoire va gonfler, non ?


 
mouais au vu de ce que fait ta fonction, deja un sacré d'appel, hein ? :D

Reply

Marsh Posté le 09-04-2003 à 16:54:27    

chrisbk a écrit :


mouais au vu de ce que fait ta fonction, deja un sacré d'appel, hein ? :D


Que je me souvienne bien, c'est bien 25 morts qu'il y a eu la dernière fois (connue) pour 10 octets de fuite ?¿?
 
 
edit : quote merdique


Message édité par nraynaud le 09-04-2003 à 16:58:33
Reply

Marsh Posté le 09-04-2003 à 16:57:15    

nraynaud a écrit :


Que je me souvienne bien, c'est bien 25 morts qu'il y a eu la dernière fois (connue) pour 10 octets de fuite ?¿?


 
Heuh ?  
 
(tain c la tempete de neige ici)

Reply

Marsh Posté le 09-04-2003 à 17:20:19    

Non mais j'hallucine !! C'est quoi ce code de merde ? On ne doit JAMAIS retourner un pointeur alloué localement, y'a rien de plus crade et de plus dangereux !!!


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 09-04-2003 à 17:23:47    

http://www.programmationworld.com/ [...] numero=109


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 09-04-2003 à 17:36:37    

philou_a7 a écrit :


Code :
  1. if (szPipo) free(szPipo)


 


 
 [:toxicavenger] inutile de tester avant de désallouer. free(NULL) est dans la norme et ne produit rien. Pas de danger donc.


Message édité par ToxicAvenger le 09-04-2003 à 17:38:30
Reply

Marsh Posté le 09-04-2003 à 17:37:38    

maestun a écrit :

Voilà, j'ai trouvé ce bout de code sur le net :

Code :
  1. buffer = (char *)malloc(strlen(nomFichier)+4+1);




 
 [:toxicavenger] ca ne se caste pas un malloc.


Message édité par ToxicAvenger le 09-04-2003 à 17:38:23
Reply

Marsh Posté le 09-04-2003 à 17:37:38   

Reply

Marsh Posté le 09-04-2003 à 17:38:29    

ToxicAvenger a écrit :


 [:toxicavenger] ca ne se caste pas un malloc.


 
Quand on essaye de le faire rentrer dans un char au lieu d'un char*, si.
 
 [:pioupiou]


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 09-04-2003 à 17:38:48    

kadreg a écrit :


 
Quand on essaye de le faire rentrer dans un char au lieu d'un char*, si.
 
 [:pioupiou]  


 
et ne reviens pas  :o

Reply

Marsh Posté le 09-04-2003 à 17:41:00    

ToxicAvenger a écrit :


 
 [:toxicavenger] inutile de tester avant de désallouer. free(NULL) est dans la norme et ne produit rien. Pas de danger donc.


 
idem pour le delete du c++ il me semble


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 09-04-2003 à 17:45:46    

je rappelle un ruc sur les cast C. ça revient à dire au compilateur "FERME TA GUEULE"
alors si en plus y en a pas besoin, faut vraiment pas en mettre

Reply

Marsh Posté le 09-04-2003 à 21:01:22    

chrisbk a écrit :

vi, un pointeur alloue (enfin la memoire sur laquelle il pointe) par malloc peut etre liberé par malloc dans n'importe quel autre endroit du prog (enfin, sauf dll mais passons).
...

C'est juste que c'est pas "propre" où y a une raison technique ?
Les DLL utilisent pourtant le même adressage virtuel, non :??:

Reply

Marsh Posté le 10-04-2003 à 00:07:22    

ToxicAvenger a écrit :


 
 [:toxicavenger] inutile de tester avant de désallouer. free(NULL) est dans la norme et ne produit rien. Pas de danger donc.


 
c'est plus propre, et encore plus si tu as hooké les malloc/free pour tester les fuites memoires ;)
 
de plus, sur certaines plateformes UN*X ou compatibles, le free sur pointeur null c'est pas top top

Reply

Marsh Posté le 10-04-2003 à 00:09:47    

mrBebert a écrit :

C'est juste que c'est pas "propre" où y a une raison technique ?
Les DLL utilisent pourtant le même adressage virtuel, non :??:  


 
une fonction d'une DLL dans un thread alloue, et la fonction qui libere se retrouve appelée dans un autre thread : bobo  :cry:  
 
de toute façon, si une fonction doit retourner un buffer, il vaut toujours mieux que l'appellant l'alloue de lui-même pour en garder le controle total
Y a qu'a voir le carnage que ca peut etre dans certaines MFC avec des alloc faites on sait pas trop comment  :sweat:

Reply

Marsh Posté le 10-04-2003 à 00:11:44    

philou_a7 a écrit :


 
c'est plus propre, et encore plus si tu as hooké les malloc/free pour tester les fuites memoires ;)
 
de plus, sur certaines plateformes UN*X ou compatibles, le free sur pointeur null c'est pas top top


 
mauvais compilo, changer compilo. La norme dit qu'on peut le faire sans danger. Si ton compilo ne le permet pas, c'est qu'il ne respecte pas la norme établie par le C. Et donc à priori, tu peux faire n'importe quoi avec ton compilo, ton code généré aura un "comportement indéfini" (bah oui, s'il respecte pas la norme, il peut faire n'importe quoi du coup).

Reply

Marsh Posté le 10-04-2003 à 00:13:09    

Oui mais dans le monde réél, tu travailles souvent sur des machines que tu n'administres pas :D
 
Donc je prefere etre trop propre ;)

Reply

Marsh Posté le 10-04-2003 à 00:16:49    

philou_a7 a écrit :

Oui mais dans le monde réél, tu travailles souvent sur des machines que tu n'administres pas :D
 
Donc je prefere etre trop propre ;)


 
non mais la c'est la norme la plus conne qui soit... c'est comme de dire:
 
"ouais, je prefere réecrire moi meme malloc, c'est pas implémenté sur mon systeme"...
 
mauvais os, changer os.

Reply

Marsh Posté le 10-04-2003 à 00:19:50    

Citation :

je prefere réecrire moi meme malloc

 :sarcastic:  
 
p'tet pas exagerer non plus ;)
 
je ne prefere appeler un free que si c'est vraiment necessaire, c'est tout ;)

Reply

Marsh Posté le 10-04-2003 à 00:31:52    

philou_a7 a écrit :

Citation :

je prefere réecrire moi meme malloc

 :sarcastic:  
 
p'tet pas exagerer non plus ;)
 
je ne prefere appeler un free que si c'est vraiment necessaire, c'est tout ;)


 
ben 1 malloc = 1 free stout  :o

Reply

Marsh Posté le 10-04-2003 à 08:51:52    

Merci à tous pour vos réponses. J'ai aussi ce cas un peu chiant :
insertion d'une cellule à la fin d'une liste chaînée :

Code :
  1. /* declarations */
  2. struct typeCellule
  3. {
  4.     char * nom;
  5.     char * prenom;
  6.     typeCellule * suivant;
  7. }
  8. typedef struct typeCellule * typeListe;
  9. /* code */
  10. /* insere une cellule a la fin d'une liste de cellules */
  11. typeListe insertCell(char * nom, char * prenom, typeListe liste)
  12. {
  13.     typeListe L;
  14.     typeListe temp;
  15.     /* allocation memoire pour une celule a inserer dans la liste chainée "liste" */
  16.     L = malloc(sizeof(struct typeCellule));
  17.     L->nom = malloc(strlen(nom) * sizeof(char) + 1);
  18.     L->prenom = malloc(strlen(prenom) * sizeof(char) + 1);
  19.     L->suivant = NULL;
  20.     /* recopie des données */
  21.     strcpy(L->nom, nom);
  22.     strcpy(L->prenom, prenom);
  23.     /* insertion de la cellule crée dans la liste */
  24.     if(liste != NULL)
  25.     {
  26.         temp = liste;
  27.         /* on va chercher la derniere cellule de la liste */
  28.         while(temp->suivant != NULL)
  29.             temp = temp->suivant;
  30.         /* chaînage de la derniere cellule avec la cellule créée */
  31.         temp->suivant = L;
  32.         return liste;
  33.        
  34.     }
  35.     else
  36.     {
  37.         liste = L;
  38.         return liste;
  39.     }
  40. }


 
question 1 : le "+ 1" dans les mallocs est-il nécessaire ?
question 2 : comment va-t-on pouvoir désallouer la mémoire allouée avec malloc() dans les fonctions appellantes ?
 
EDIT : précision supplémentaire : ce bout de code est appellé plein de fois car utilisé dans un service Win2000 (donc prog qui tourne en permanence), d'où la nécessité de libérer de la RAM !


Message édité par maestun le 10-04-2003 à 09:55:35
Reply

Marsh Posté le 10-04-2003 à 10:06:47    

1/ oui, le +1 est necessaire : strlen te donne la taille de la chaine sans le \0 final, donc tu rajoutes 1 pour prendre celui-ci en compte
 
2/ bah c'est simple : comme tout free de liste qui se respecte, tu va parcourir ta liste pour la liberer ;)
Le plus simple est de faire une fonction recursive pour ca :
 
en pseudo code ca donne a peu pres ca :
 
Libere(liste)
{
  si (liste)
  {
    si (liste->suivant) alors Libere(liste->suivant)
    free(liste->champ_de_donnée) // pour chaque champ...
    free(liste)
    liste=null
  }
}

Reply

Marsh Posté le 10-04-2003 à 10:23:06    

philou_a7 a écrit :

1/ oui, le +1 est necessaire : strlen te donne la taille de la chaine sans le \0 final, donc tu rajoutes 1 pour prendre celui-ci en compte
 
2/ bah c'est simple : comme tout free de liste qui se respecte, tu va parcourir ta liste pour la liberer ;)
Le plus simple est de faire une fonction recursive pour ca :
 
en pseudo code ca donne a peu pres ca :
 
Libere(liste)
{
  si (liste)
  {
    si (liste->suivant) alors Libere(liste->suivant)
    free(liste->champ_de_donnée) // pour chaque champ...
    free(liste)
    liste=null
  }
}


Merci bcp !
si je comprends bien, il est possible de faire "free(ptr)" si le "ptr = malloc(x)" a été fait dans une autre fonction ?

Reply

Marsh Posté le 10-04-2003 à 10:26:54    

oui, tant que tu ne te balade pas entre plusieurs threads, ou dlls, etc ;)

Reply

Marsh Posté le 10-04-2003 à 11:38:06    

Harkonnen a écrit :

Non mais j'hallucine !! C'est quoi ce code de merde ? On ne doit JAMAIS retourner un pointeur alloué localement, y'a rien de plus crade et de plus dangereux !!!


 
Je vois pas en quoi c'est dangeureux. il suffit de tester à la sortie. Jette un oeil sur les listes et les files. que font les fonctions d'après toi ?

Reply

Marsh Posté le 10-04-2003 à 11:49:51    

JagStang a écrit :


 
Je vois pas en quoi c'est dangeureux. il suffit de tester à la sortie. Jette un oeil sur les listes et les files. que font les fonctions d'après toi ?


 
Rien à voir, ces fonctions font une allocation sur le heap et non localement. Une variable locale (à une fonction) est désallouée à la fin de la fonction donc il n'est pas possible de la retourner (enfin si, c'est possible mais c'est mal :D)


---------------
"Dieu a exploité tous nos complexes d'infériorité, en commençant par notre incapacité de croire à notre propre divinité." - Emil Michel Cioran
Reply

Marsh Posté le 10-04-2003 à 12:20:42    

JagStang a écrit :


 
Je vois pas en quoi c'est dangeureux. il suffit de tester à la sortie. Jette un oeil sur les listes et les files. que font les fonctions d'après toi ?


Je plussoie Tetragrammaton !
Par définition, une variable allouée localement est détruite à la fin de la fonction. Donc si tu retournes un pointeur non alloué, la zone mémoire à laquelle il fait référence n'existera plus en sortant de la fonction et tu te retrouves avec un pointeur fou, à moins que tu n'alloues la mémoire dans la fonction. Mais ça veut dire que tu dois la libérer en dehors de la fonction, ce qui est dangereux dans le cas d'un projet sur lequel plusieurs personnes travaillent : tu peux être sur que 9 fois sur 10, la RAM ne sera pas libérée.
 
Si on tient absolument à retourner un pointeur, le mieux est de l'allouer avant d'appeler la fonction.


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 10-04-2003 à 12:27:49    

Tetragrammaton IHVH a écrit :


 
Rien à voir, ces fonctions font une allocation sur le heap et non localement. Une variable locale (à une fonction) est désallouée à la fin de la fonction donc il n'est pas possible de la retourner (enfin si, c'est possible mais c'est mal :D)


Oui effectivement, que le pointeur soit local ou global ne change rien, la mémoire est toujours allouée sur le tas, thanx God..;-)
Si c'est possible, de facon saine, car ta variable locale est forcément recopiée pour retourner la valeur à l'appelant dans le cadre de la convention de passage de paramètres en vigueur sur le compilo.


---------------
"We are not enemies, but friends. We must not be enemies. Though passion may have strained, it must not break our bonds of affection. The mystic chords of memory will swell when again touched, as they surely will be, by the better angels of our nature."
Reply

Marsh Posté le 10-04-2003 à 12:29:11    

On peut faire un truc genre ca pour alloue en dehors de la fonction.
 

Code :
  1. char* pBloc = NULL;
  2. pBloc = (char*) malloc(lafonction(pBloc, .... les params));
  3. if (pBloc != NULL)
  4. lafonction(pBloc, .... les params);
  5. else
  6. erreur d'alloc
  7. int lafonction(char* pBloc = NULL, ... les params) {
  8. if (pBloc == NULL)
  9.  return LaTailleDontOnABesoin;
  10. ... reste de la fonction
  11. return 1;
  12. }


Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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