Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

8 réponses
Avatar
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

8 réponses

Avatar
espie
In article <ioeil3$8rh$,
cLx 'aimail.com.almost.invalid> wrote:
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.
Avatar
cLx
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
Avatar
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.

J'imagine que sizeof(char) c'est pour faire joli ou parce que ça vient
d'une macro ?
Avatar
cLx
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
Avatar
Marc
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.
Avatar
Erwan David
Marc écrivait :

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é
Avatar
espie
In article <ioes45$jf6$,
cLx 'aimail.com.almost.invalid> wrote:
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.
;-)
Avatar
Xavier Roche
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.]