Petite question concernant malloc et free...

kod32 Messages postés 46 Date d'inscription mercredi 5 mai 2004 Statut Membre Dernière intervention 13 novembre 2004 - 6 juin 2004 à 20:01
kod32 Messages postés 46 Date d'inscription mercredi 5 mai 2004 Statut Membre Dernière intervention 13 novembre 2004 - 6 juin 2004 à 22:15
Salut,
je me pose une question depuis un petit moment et je pense que vous avez la réponse...

Quand on alloue quelques octets via malloc, si on évite l'appel de free pour libérer, la libération se fait lors de la fermeture du programme. Mais qu'en est il pour la fin d'une fonction...

Je m'explique par un exemple. Voici une fonction basique de convertion minuscule -> majuscule :
---------------
char *min_maj(char *string)
{
int c, i;
char buf[1];
char *pStr = (char *)malloc(strlen(string)+1);
memset(pStr, 0, strlen(pStr));
for(i=0; i <= strlen(string); i++)
{
c = string[i];
if((c <= 122) && (c >= 97))
c -= 32;
sprintf(buf, "%c", c);
strcat(pStr, buf);
}
string = pStr;
return string;
}
---------------
pour libérer l'allocation de pStr, il faudrait mettre un free(pStr) juste avant return string;
Or si on fait cela, la fonction ne retournera plus rien puisque string pointe sur la mémoire allouée.
Est ce que la mémoire est libérée automatiquement à la fin de l'exécution de la fonction ? Si ce n'est pas le cas, que fais t'on en général pour la libération d'un pointeur malloqué en local dans une fonction ?

Merci

8 réponses

cs_AlexMAN Messages postés 1536 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 24 mai 2009 2
6 juin 2004 à 20:10
Bon d'abord jne pense pas ke retourner une chaine de caractere de classe d'allocation automatik soit une bonne idée, car a la fin de la fonction, cette chaine sera "detruite" donc ta fonction pointera vers un emplacement ki pourrait etre modifié par d'autres données...
J'utilise une chaine globale (static) ke je retourne puis ke je libere apres l'appel de la fonction, jne sais pas si c bien, mais c ske je fais, et comme ca t sur de bien liberer l'espace memoire alloué...

Voila, jespere t'avoir repondu

++

Alhexman
0
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 19
6 juin 2004 à 21:07
A chaque malloc doit correspondre son free !!!
Aucune alloc dynamique ne se libere toute seule ni n'est detruite en sortie de fonction.
Essaie ceci pour t'en convaincre.

char* NouvChaine(char *psz)
{
char *pbuff;
pbuff = (char*) malloc(strlen(psz) + 8);
if(pbuff) {
strcpy(pbuff, "Salut ");
strcpy(pbuff + 6, psz);
}
return pbuff;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE x, PSTR y, int z)
{
char *c;
c = NouvChaine("la foule");
if(c) {
MessageBox(0, c, szappname, 0);
free(c);
}
return 0;
}

ciao...
BruNews, Admin CS, MVP Visual C++
0
kod32 Messages postés 46 Date d'inscription mercredi 5 mai 2004 Statut Membre Dernière intervention 13 novembre 2004
6 juin 2004 à 21:12
donc dans ton exemple, le fait de faire un free(c) libère la mémoire allouée dynamiquement dans la fonction NouvChaine() ?
0
cs_AlexMAN Messages postés 1536 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 24 mai 2009 2
6 juin 2004 à 21:16
BruNews, ds ton exemple, une fonction "peut " modifier l'espace alloué a c non ? par une autre allocation ou kelk chose come ca, dis moi si jme trompe
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 19
6 juin 2004 à 21:25
En theorie, l'espace alloue est reserve et ne pourra pas etre touche par une autre fonction. Rien n'empeche bien entendu de vouloir ecrire plus long qu'il n'y a d'espace reserve, auquel cas plantage ou ecrasement de donnees a prevoir.
free(c) libere bien la memoire allouee dans la fonction appelee, il ne faut surtout pas modifier c, du genre c++ ou autre fantaisie mais bien passer a free le resultat de malloc.

ciao...
BruNews, Admin CS, MVP Visual C++
0
kod32 Messages postés 46 Date d'inscription mercredi 5 mai 2004 Statut Membre Dernière intervention 13 novembre 2004
6 juin 2004 à 21:58
ok, dc si j'ai bien compris, si j'utilise ma fonction comme ceci :
int main(int argc, char *argv[])
{
char *pString = min_maj("abcdef");
printf("%s\n", pString);
free(pString);
system("pause");
return 0;
}

ma mémoire sera bien libérée ?
0
BruNews Messages postés 21041 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 19
6 juin 2004 à 22:06
OUI, free libere bien le pointeur retourne par malloc.

Par contre dans ta func:
char *pStr = (char *)malloc(strlen(string)+1);
memset(pStr, 0, strlen(pStr));
strlen(pStr) ???????
strlen compte de nombre d'octets jusqu'au 1er NULL trouve. Ici comment savoir ce qu'il y a dans cet emplacement memoire ? Y a-t-il meme un zero ?

len = strlen(string)+1;
char *pStr = (char *)malloc(len);
memset(pStr, 0, len);

Autre truc:
char buf[1];
tu aurais mis: char buf, c'etait idem.
On ne fera jamais une chaine de type C avec moins de 2 octets, il faut un ZERO final.

ciao...
BruNews, Admin CS, MVP Visual C++
0
kod32 Messages postés 46 Date d'inscription mercredi 5 mai 2004 Statut Membre Dernière intervention 13 novembre 2004
6 juin 2004 à 22:15
Un grand merci à toi BruNews !
0