Pointeurs statiques, malloc, free, et appels de fonctions multiples

Le
cLx
Bonjour,

Je fais une petite bidouille, ça fonctionne sous win, mais j'ai une petite
surprise sous Linux Debian.

J'ai une fonction appelée plusieurs fois pour découper le flux de données en
quantité de mémoire passant dans le buffer. Dans la fonction, pour ne pas
perdre les états de ma moulinette entre les appels. J'ai des pointeurs
initialisés a null a chaque fois que je veux repartir de zero, et je les
alloues avec malloc() quand j'en ai besoin avec par exemple :

static char *username = NULL;
[]
if (username != NULL) { free(username); username = NULL; }
username = malloc((o)*sizeof(char));

Le problème, c'est que on dirait que free() n'est pas du tout content quand
la fonction s'est terminée et relancée entretemps. Est-ce que quelqu'un sait
comment éviter que tout ce que j'ai alloué disparaisse comme ça ?

Si c'est une sorte de ramasse-miettes, comment le désactiver ?

Merci d'avance,
cLx

*** glibc detected *** ./program: free(): invalid pointer: 0x0804e638 ***
= Backtrace:
/lib/i686/cmov/libc.so.6[0xb7eb8764]
/lib/i686/cmov/libc.so.6(cfree+0x96)[0xb7eba966]
./program[0x804a7a5]
./program[0x8049c44]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7e60455]
./program[0x80488b1]
= Memory map: ==
08048000-0804b000 r-xp 00000000 fe:01 310158 program
0804b000-0804c000 rw-p 00002000 fe:01 310158 program
0804c000-0806e000 rw-p 0804c000 00:00 0 [heap]
b7d00000-b7d21000 rw-p b7d00000 00:00 0
b7d21000-b7e00000 p b7d21000 00:00 0
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
espie
Le #23290971
In article cLx
Bonjour,

Je fais une petite bidouille, ça fonctionne sous win, mais j'ai une petite
surprise sous Linux Debian.

J'ai une fonction appelée plusieurs fois pour découper le flux de données en
quantité de mémoire passant dans le buffer. Dans la fonction, pour ne pas
perdre les états de ma moulinette entre les appels. J'ai des pointeurs
initialisés a null a chaque fois que je veux repartir de zero, et je les
alloues avec malloc() quand j'en ai besoin avec par exemple :

static char *username = NULL;
[...]
if (username != NULL) { free(username); username = NULL; }
username = malloc((o)*sizeof(char));

Le problème, c'est que on dirait que free() n'est pas du tout content quand
la fonction s'est terminée et relancée entretemps. Est-ce que quelqu'un sait
comment éviter que tout ce que j'ai alloué disparaisse comme ça ?

Si c'est une sorte de ramasse-miettes, comment le désactiver ?



Non, c'est tres certainement des erreurs que tu as faites ailleurs.
Le probleme des erreurs d'allocation, c'est qu'elles se manifestent
apres que tu aies commis l'erreur. En general, si un free() rale, et que le
pointeur que tu lui passes est correct et alloue par malloc(), c'est
parce que tu as utilisee de la memoire deja liberee/fait un debordement de
capacite sur une autre allocation.

Il n'y a pas besoin de chercher de magie ailleurs. C'est tres certainement
ton code qui est faux. Ca marche par accident sous windows, parce que la
carte memoire n'est pas la meme, l'allocateur n'est pas le meme, et donc que
les memes erreurs ont tape dans un coin de la memoire qui ne plante pas
directement ton programme.
cLx
Le #23290981
On 17/04/2011 14:40, Marc Espie wrote:
Non, c'est tres certainement des erreurs que tu as faites ailleurs.
Le probleme des erreurs d'allocation, c'est qu'elles se manifestent
apres que tu aies commis l'erreur.
En general, si un free() rale, et que le
pointeur que tu lui passes est correct



checked.

et alloue par malloc(),



checked.

c'est
parce que tu as utilisee de la memoire deja liberee/



checked, impossible dans mon cas.

fait un debordement de
capacite sur une autre allocation.



...
*gros doute*

- username = malloc((o)*sizeof(char));
+ username = malloc((o)*sizeof(char)+1);
(même chose avec les autres champs)

Rha, c'était si simple et si bête !

Il n'y a pas besoin de chercher de magie ailleurs. C'est tres certainement
ton code qui est faux. Ca marche par accident sous windows, parce que la
carte memoire n'est pas la meme, l'allocateur n'est pas le meme, et donc que
les memes erreurs ont tape dans un coin de la memoire qui ne plante pas
directement ton programme.



J'ai fini par réussir a le faire planter pour la même raison d'une autre
façon sous windows comme ça pas de jaloux ;)

Aller je vais essayer sous BSD maintenant.

Merci.

--
cLx
Marc
Le #23291011
cLx wrote:

- username = malloc((o)*sizeof(char));
+ username = malloc((o)*sizeof(char)+1);
(même chose avec les autres champs)

Rha, c'était si simple et si bête !



Sous linux, valgrind est très bien pour détecter ce genre de chose.

J'imagine que sizeof(char) c'est pour faire joli ou parce que ça vient
d'une macro ?
cLx
Le #23291061
On 17/04/2011 15:21, Marc wrote:
cLx wrote:

- username = malloc((o)*sizeof(char));
+ username = malloc((o)*sizeof(char)+1);
(même chose avec les autres champs)

Rha, c'était si simple et si bête !



Sous linux, valgrind est très bien pour détecter ce genre de chose.



C'est noté, je vais aller voir ça.

J'imagine que sizeof(char) c'est pour faire joli ou parce que ça vient
d'une macro ?



Pour faire joli. Celui avec qui je bosses sur le code aime bien mettre ça et
comme je suis chiant pour le style d'indentation, je veux pas _trop_ le
contrarier non plus.

Ça serait plus joli sans ?

--
cLx
Marc
Le #23291101
cLx wrote:

On 17/04/2011 15:21, Marc wrote:
cLx wrote:

- username = malloc((o)*sizeof(char));
+ username = malloc((o)*sizeof(char)+1);
(même chose avec les autres champs)






[...]
J'imagine que sizeof(char) c'est pour faire joli ou parce que ça vient
d'une macro ?



Pour faire joli. Celui avec qui je bosses sur le code aime bien mettre ça et
comme je suis chiant pour le style d'indentation, je veux pas _trop_ le
contrarier non plus.



Excellente philosophie.

Ça serait plus joli sans ?



Des goûts et des couleurs...
Certains trouveraient que multiplier par la constante 1 (écrite avec 12
caractères) est peu utile, mais dans le contexte d'un malloc ça ne
choque pas. Enfin il faudrait peut-être que la multiplication s'applique
aussi au nouveau +1, pour être cohérent.
Erwan David
Le #23291271
Marc
cLx wrote:

- username = malloc((o)*sizeof(char));
+ username = malloc((o)*sizeof(char)+1);
(même chose avec les autres champs)

Rha, c'était si simple et si bête !



Sous linux, valgrind est très bien pour détecter ce genre de chose.



ElectricFence aussi peut être utile.


--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
espie
Le #23291651
In article cLx
J'imagine que sizeof(char) c'est pour faire joli ou parce que ça vient
d'une macro ?



Pour faire joli. Celui avec qui je bosses sur le code aime bien mettre ça et
comme je suis chiant pour le style d'indentation, je veux pas _trop_ le
contrarier non plus.

Ça serait plus joli sans ?



Ca eviterait qu'on te prenne d'office pour un debutant.
;-)
Xavier Roche
Le #23291671
Le 17/04/2011 21:00, Marc Espie a écrit :
J'imagine que sizeof(char) c'est pour faire joli ou parce que ça vient
d'une macro ?




Ca eviterait qu'on te prenne d'office pour un debutant.
;-)



Bof. Le mettre ne coûte rien, et le jour où le char se transforme en
wchar_t, le code est plus facile à changer.

[ Moi, du reste, j'aurais collé *sizeof(username[0]), le tout dans une
macro propre qui renvoi un machin typé, mais bon.]
Publicité
Poster une réponse
Anonyme