Libérer la mémoire et fonction recvfrom - C - Programmation
Marsh Posté le 05-01-2007 à 10:33:06
J'ai essayé de les ajouter mais à l'exécution j'ai une belle erreur à chaque fois... je ne sais pas si il y a un ordre à respecter, si j'essaye dans l'ordre inverse de déclaration ça ne fonctionne pas.
D'ailleurs si je ne fais que "free(icmp);" j'ai aussi l'erreur.
L'erreur est du type " *** glibc detected *** munmap_chunk() : invalid pointer ".
Marsh Posté le 05-01-2007 à 10:37:36
C'est normal.
Le malloc :
icmp = (struct icmpheader *) malloc(sizeof(struct icmpheader)); |
Puis, quelques lignes en dessous :
icmp = (struct icmpheader *) (packet + sizeof(struct ipheader)); |
Le pointeur vers la zone mémoire que tu as allouée s'est donc paumé dans la nature, et ce que tu donnes à free() ne correspond plus à ce que t'avais retourné malloc().
Tu essaies donc de libérer une zone mémoire qui n'a pas à l'être, tandis que celle que tu devais désallouer est quelque part dans ton segment.
Marsh Posté le 05-01-2007 à 10:44:49
Elmoricq a écrit : C'est normal.
|
Un cas typique de 'fuite mémoire'...
Marsh Posté le 05-01-2007 à 10:59:55
Merci pour vos réponses rapides
Je viens d'essayer en supprimant les deux lignes :
Code :
|
Ainsi il n'y a plus de fuite mémoire
Mais est-ce que c'était important d'allouer la mémoire à cet endroit?
Marsh Posté le 05-01-2007 à 11:03:15
XK a écrit : Mais est-ce que c'était important d'allouer la mémoire à cet endroit? |
"Allouer de la mémoire" signifie, très clairement, "dégager un espace libre pour y stocker des données".
C'est ce que fait malloc(), c'est pourquoi tu lui indiques la taille dont tu as besoin, et le pointeur retourné est l'adresse de départ de cette mémoire fraîchement allouée.
Ici, visiblement, de cet espace mémoire tu n'en as pas l'usage. Pourquoi en avoir alloué ?
Marsh Posté le 05-01-2007 à 11:05:16
XK a écrit : Je viens d'essayer en supprimant les deux lignes :
|
Un peu comme si tu as un bobo sur la main et que le chirurgien te coupe le bras. Plus de main => plus de bobo
XK a écrit : Mais est-ce que c'était important d'allouer la mémoire à cet endroit? |
Oui !
Ce qu'il faut que tu fasses, c'est ajouter les free() correspondants comme dit plus haut dans le topic. Pour le pointeur icmp, qui est modifié après le retour de malloc (problème soulevé par Elmoricq), il faut que tu sauvegardes sa valeur juste après le retour de malloc, et que tu fasses ton free() sur le pointeur sauvegardé.
[edit] En lisant en diagonale, j'avais pas vu que les espaces alloués étaient pas utilisés
Marsh Posté le 05-01-2007 à 11:11:56
Effectivement, je n'ai pas écris ce code qui reste assez abstrait pour moi, mais il semble que l'espace alloué n'est pas utilisé donc inutile
Si vous trouvez d'autres choses absurdes ça m'interesse
Marsh Posté le 05-01-2007 à 13:34:32
pourquoi tu fais tous ces allocations dynamiques ? M'est d'avis que tu débute et que tu fais un mélange pointeur / malloc.
Vire tes malloc.
Marsh Posté le 12-01-2007 à 11:25:07
J'ai tout simplifié, les malloc sont bien libérés désormais.
Par contre j'ai essayé de changer la fonction recv() en recvfrom() :
Code :
|
Mais la fonction me renvoi toujours "-1" alors que recv me renvoyait bien la taille du paquet.
Une idée d'où se trouve mon erreur?
Merci
Marsh Posté le 12-01-2007 à 12:26:17
XK a écrit : Par contre j'ai essayé de changer la fonction recv() en recvfrom() :
|
On ne remplace pas recv() par recvfrom() au gré des vents ou de l'humeur du jour... La première fonction est pour le mode connecté (Paquets TCP, par exemple), la deuxième est pour le mode non connecté (Datagrams UDP, par exemple)
Marsh Posté le 12-01-2007 à 12:32:31
XK a écrit : Par contre j'ai essayé de changer la fonction recv() en recvfrom() :
|
Hum... j'ai la bizarre sensation que tu utilises ces fonctions comme une recette magique. On remplace ceci par cela un peu au hasard et on regarde...
Chaque fonction a une utilité précise et c'est quand on connait les fonctions qu'on peut arriver à trouver laquelle sera le plus utile pour résoudre le problème.
En l'occurrence, "recv()" est une fonction destinée à recevoir des infos d'une socket ouverte en prococole TCP, c'est à dire avec le canal source/destinataire déjà créé et le chemin bien établi. En revanche, la fonction "recvfrom()" est une fonction destinée à recevoir des infos d'une socket ouverte en protocle UDP, c'est à dire sans chemin établi. C'est la fonction qui se charge d'établir le chemin à la demande. Et c'est aussi pour ça que 2 appels simultanés à "recvfrom()" peuvent voir le 2° résultat arriver avant le 1er parce que le 2° chemin établi aura été plus court que le premier.
En tout cas on ne peut pas interchanger les 2 fonctions...
Commence un peu par te familiariser avec les bases du C, puis t'arrivera au malloc/free puis ensuite tu pourras attaquer les comm. réseau avec les sockets. Mais entre temps t'auras pas mal de trucs à voir...
[edit] Toasted
Marsh Posté le 12-01-2007 à 14:05:28
J'aurais pensé que c'était mieux de spécifier la source du message à recevoir, bien entendu ici nous sommes en mode connecté donc ça n'a que peu d'importance...
Sur le net on trouve parfois n'importe quoi, entre autre conseiller d'utiliser une fonction plutôt qu'une autre alors qu'on en a pas l'interrêt... Donc je resterai avec recv() qui fonctionne bien et je le saurai pour la prochaine fois, merci
Marsh Posté le 12-01-2007 à 17:40:53
XK a écrit : bien entendu ici nous sommes en mode connecté |
Oui, j'avais remarqué
XK a écrit : donc ça n'a que peu d'importance... |
Au contraire, cela en a énormément en ce sens qu'on ne peut pas utiliser "recvfrom()". Ce n'est pas que t'as le choix entre les deux et que cela importe peu d'en prendre l'une plutôt que l'autre, c'est que t'as absolument pas le choix et si tu choisis la mauvaise fonction ben rien ne marchera !!!
En revanche, tu peux choisir entre "recv()" et "read()". La première est spécifiquement adaptée aux sockets, la seconde est adaptée à toute entrée Unix (donc la socket en fait partie). Bien entendu "recv()" est mieux mais "read()" marche aussi. C'est comme si tu faisais de la copie de chaîne avec "memcpy()" plutôt que "strcpy()". Même si strcpy() est spécialement faite pour ça, memcpy() marche aussi...
Marsh Posté le 12-01-2007 à 17:59:56
Sve@r a écrit : En revanche, tu peux choisir entre "recv()" et "read()". La première est spécifiquement adaptée aux sockets, la seconde est adaptée à toute entrée Unix (donc la socket en fait partie). Bien entendu "recv()" est mieux mais "read()" marche aussi. |
Surtout recv() est plus portable que read()...
Marsh Posté le 05-01-2007 à 10:12:58
Bonjour
J'ai écris un programme me permettant de faire des pings sous Linux, utilisant des RAW Socket ICMP.
A chaque ping, la fonction Ping(IP) est appellée. Le code a été repris en grande partie sur Internet, je n'ai pas une connaissance poussée du langage C, donc j'ai du mal à trouver comment libérer toute la mémoire utilisée par la fonction Ping que voici :
Lorsque le programme tourne en boucle, la mémoire utilisée grandie petit à petit...
Merci de me dire ce que je dois ajouter à la fin de la fonction pour que toute la mémoire soit libérée
Message édité par XK le 12-01-2007 à 11:19:44