7
votes

Est-ce que c envoi le tampon gratuit?

J'ai une question sur la méthode d'envoi de C.

char *buffer = (char *)malloc(100*sizeof(char));
send(s, buffer, 100*sizeof(char), MSG_NOSIGNAL);
free(buffer);


0 commentaires

5 Réponses :


8
votes

Envoyer ne libère pas le tampon. Vous devez libérer ça. En plus du fait qu'il n'ait tout simplement pas été conçu de cette façon (les fonctions de socket sont indépendantes des fonctions du tas), SEND [SAVOIR »si la mémoire devrait être libérée puisqu'elle pourrait être un pointeur au milieu d'une pièce allouée de mémoire ou cela pourrait être un pointeur pour empiler des données.

Il devrait être "sûr" pour libérer immédiatement le tampon après l'envoi d'appel, car la fonction aura copié les données à ses propres tampons internes. Le code que vous montrez ne causerait pas de problème de corruption (bien que je soupçonne qu'il y ait plus de code impliqué car le tampon n'est pas initialisé comme indiqué). Il est possible que le tas soit corrompu plus tôt dans le processus et ne provoque pas une exception avant la suite (par exemple, le libre après l'envoi).

La valeur de retour de Envoyer indique le nombre d'octets envoyés avec succès (bien que cela ne soit pas nécessairement livré avec succès). Donc, alors que ce serait «sûr» de libérer, vous perdrez les données non définies si ce n'est tout été envoyé. Si l'ensemble du tampon n'a pas été envoyé, vous auriez besoin d'appeler à nouveau avec le montant restant.


2 commentaires

@Tim: Oui, il serait prudent de la libérer juste après l'envoi, bien que vous souhaitiez vérifier la valeur de retour de l'envoi. Il indique le nombre d'octets envoyés avec succès.


Je vois, mais si tous les octets où l'envoi avec succès et si certains octets ne sont pas?



0
votes

Envoyer () ne libère pas le tampon. Si vous avez des problèmes doubles, vous devriez rechercher probablement votre liberté et vérifier comment vous y arriverez.


0 commentaires

1
votes

Vous pouvez gratuit code> la mémoire tampon après l'envoi d'appel code> appelle renvoie, notant les éléments suivants:

  • Le tampon entier n'a peut-être pas été envoyé. LI>
  • L'appel renvoie le nombre d'octets que le noyau a copié dans ses propres tampons. Le reste que vous devriez garder. Li> ul>

    Ce code peut vous aider à comprendre ce qui se passe, mais en aucun cas, vous devez baser la vôtre à ce sujet: P>

    char *buf; // sizeof(*buf) must be 1 for pointer arithmetic
    ssize_t sent = send(fd, buf, len, 0);
    if (sent != -1) { // no error
        // move the unsent bytes to the start of the buffer
        memmove(buf, buf + sent, len - sent);
        // resize the buffer to fit the left over bytes
        buf = realloc(buf, len - sent);
    }
    


0 commentaires

0
votes

En général, il serait très non autorisé si une fonction API libérerait un tampon. La seule fonction que je connaisse qui libère un tampon est "libre" ...

Parfois, les fonctions allouent la mémoire que vous devez libérer après les utiliser, par ex. STRUP

Il existe certaines fonctions, où vous ne pouvez pas libérer le tampon directement après les utiliser. Par exemple, dans .NET, vous ne pouvez pas disposer du pointeur de données d'un bitmap s'il est toujours utilisé dans une emballage bitmap.


1 commentaires

Realloc () peut également libérer la mémoire allouée à partir du magasin libre, si elle est passée une taille de zéro. Sinon, vous êtes correct - seuls les fonctions d'API de tas tels que free () et realloc () peuvent libérer la mémoire obtenue à partir du magasin libre.



0
votes

Il ressort de votre description comme si vous souffrez de votre code en utilisant un pointeur après avoir été libéré. Il y a de bonnes façons solides d'attraper ce type de problème, puis il y a des hacks rapides. Voici un piratage rapide: xxx

Cette macro, que vous voudriez inclure dans votre fichier d'en-tête ou la première ligne de votre projet, remplace vos appels gratuitement pour que:

  1. La mémoire est toujours free () 'd, la notation (gratuit) (p) force le compilateur C à évaluer (gratuit) En tant que symbole de la fonction, pas une expansion macro.
  2. Le pointeur est réglé sur une valeur inaccessible, 1. La valeur null (0) n'a pas été utilisée car free () ne se plaingait pas s'il est passé Null . Passer une "valeur de pointeur" de 1 devrait déclencher un rapport d'erreur.

    Vous pouvez constater qu'après avoir utilisé cette macro, votre code a été détaché d'un pointeur obsolète. Une fois que vous avez GRATUIT 'de mémoire D, les pointeurs d'utilisation indiquent la même mémoire et indiqueront temporairement sur les mêmes valeurs en mémoire - jusqu'à une seconde utilisation de cette mémoire qui lisse ces valeurs. Pour cette raison, votre programme peut être capable de fonctionner pour quelques lignes à l'aide de pointeurs rassis. Changer chaque pointeur sur 1 quand il devient rassasié attrapera ce tout de suite.


0 commentaires