IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Fuite de mémoire ?


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut Fuite de mémoire ?
    Je met d'abord mon code :


    [...]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	char *buffer;
    	while(1) {
    		buffer = getsource(lines2, lines, NULL);
    		// traitement
    		free(buffer);
    	}
    [...]

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    char *getsource(char *quoi, char *ou, char *page) 
    {
    	int sock;
    	char *input = malloc((sizeof(*input) * (MAX_IO +1)));
     
    	if (input == NULL) return 0;
     
    	size_t current_size = (MAX_IO + 1), total = 0, t = 0;
     
    	sock = init_sock("193.252.242.142", 80);
    	if (sock == 0) {
    		free(input);
    		return 0;
    	}
    	sendSock(sock, "blabla %s", quoi);
    	// J'en ai plusieur des sendSock comme ca
     
    	while((t = recv(sock, input + (total), 2048, 0)) > 0) {
    		total += t;
     
    		if ((total+2048) > current_size) {
     
    			current_size += (MAX_IO+1);
    			input = realloc(input, current_size);
    			if (input == NULL) return 0;
    		}
     
    	}
    	input[total] = '\0';
            closesocket(sock);
     
    	return input;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    SOCKET init_sock(char *ip, unsigned int port)
    {
            SOCKET sock;
            SOCKADDR_IN sin;
     
            sock = socket(AF_INET, SOCK_STREAM, 0);
            sin.sin_addr.s_addr                     = inet_addr(ip);
            sin.sin_family                          = AF_INET;
            sin.sin_port                            = htons(port);
     
            if (connect(sock, (SOCKADDR *)&sin, sizeof(sin)) == -1) {
                    return 0;
            }
     
            return sock;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    int sendSock(SOCKET sock, char *buf, ...)
    {
    	char buff[MAX_IO+1]; // A changer car lil
     
    	int len, t_bytes = 0, r_bytes, n;
     
    	memset(buff, '\0', MAX_IO+1);
     
    	va_list val;
     
    	va_start(val, buf);
    	vsnprintf(buff, MAX_IO - 2, buf, val);
    	va_end(val);	
     
     
     
    	len = strlen(buff);
    	r_bytes = len;
     
    	while(t_bytes < len) {
    		n = send(sock, buff+t_bytes, r_bytes, 0);
    		if (n == -1) {
     
    			break; 
    		}
    		t_bytes += n;
    		r_bytes -= n;
    	}
     
    	len = t_bytes;
     
    	return (n==-1 ? -1: 0);
    }
    Mon problème :

    Sous Linux en natif : Pas de fuite de mémoire
    Compilé avec gcc-mingw (sous Linux) et lancé avec wine : Pas de fuite de mémoire
    Compilé avec gcc-mingw (sous Linux) et lancé directement sous Windows : La mémoire monte, monte, monte.....(BOOM)

    La fuite ne peux venir que du malloc ? des variables dans la stack Oo (sendSock que j'appel souvent) ?

    Merci

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Une remarque d'abord : écrire du code lisible n'est pas un handicap !!!!!!!


    Pourquoi écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    		t_bytes += n;
    		r_bytes -= n;
     
    	return (n==-1 ? -1: 0);

    et non pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		t_bytes = t_bytes + n;
    		r_bytes r_bytes - n ;
     
      	if ( n==-1 )
                return -1;
            else
                return 0;
    Trop dur à taper ??? Mais qu'est-ce que c'est plus clair, quand tu reviendras
    dessus dans 10 ans.... ou que quelqu'un d'autre reprendra ta code.. Ou que tu voudras l'écrire dans un autre langage....


    Bon, ensuite :


    • 1) libération de buffer ne teste pas si buffer est NULL ou non.
    • 2) incohérences entre le fait de tester input par rapport à NULL er retourner 0
    • 3) si le realloc ne marche pas, mémoire perdue.. Utiliser une varaible intermédiaire.

  3. #3
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Bonjour,

    Merci de ta réponse.

    Qui y'a t'il de sale dans les opérateurs ternaires ?

    Pour le reste ok , mais ce n'est visiblement pas cela qui provoque la fuite.

    Merci

  4. #4
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Bonjour,

    l'operateur ternaire n'est pas la syntaxe la plus lisible inventée.
    C'est a peu pres tout je pense.

  5. #5
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    C'est vrai, cela dit cela ne résous pas mon problème

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Je n'ai rien contre l'opérateur ternaire ici, il ne gène pas du tout la lisibilité dans ce cas (j'ai déjà vu des opérateurs ternaires illisibles, et c'est vraiment autre chose).

    Par contre, cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (input == NULL) return 0;
    Leake à la fois la mémoire existante (une erreur commune quand on joue avec realloc()) et le socket...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par |PaRa-BoL Voir le message
    Mon problème :

    Sous Linux en natif : Pas de fuite de mémoire
    Compilé avec gcc-mingw (sous Linux) et lancé avec wine : Pas de fuite de mémoire
    Compilé avec gcc-mingw (sous Linux) et lancé directement sous Windows : La mémoire monte, monte, monte.....(BOOM)

    La fuite ne peux venir que du malloc ? des variables dans la stack Oo (sendSock que j'appel souvent) ?
    Dans SendSock(), n n'est pas initialisé...

    En mode 'Windows', il manque l'initiation du gestionnaire de sockets (WSA...)

  8. #8
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Dans SendSock(), n n'est pas initialisé...
    Merci

    En mode 'Windows', il manque l'initiation du gestionnaire de sockets (WSA...)
    Si je le fait au start du programme et non pas à chaque boucle pour éviter de recharger à chaque fois winsock. (Je clean WSA à la fin)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int main(int argc, char **argv)
    {
            //[...]
            WSADATA WSAData;
            WSAStartup(MAKEWORD(2,2), &WSAData);
            //[...] ma boucle
            WSACleanup();
            //[...]
    }
    Mais tu leakes toujours le socket...
    En effet je fait le closesocket() que si il n'y a pas d'erreur. (corrigé)

    Mais le leak que j'ai ce produit quoi qu'il arrive à chaque boucle même après appel de closesocket() et avoir free() mon buffer.

    Je me demande alors si le problème ne peux pas venir de sendSock() ? Il est impossible d'avoir une fuite avec des variables dans la pile ?

    Merci

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par |PaRa-BoL Voir le message
    Je met d'abord mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    	while((t = recv(sock, input + (total), 2048, 0)) > 0) {
    		total += t;
     
    		if ((total+2048) > current_size) {
     
    			current_size += (MAX_IO+1);
    			input = realloc(input, current_size);
    			if (input == NULL) return 0;
    		}
     
    	}
    	input[total] = '\0';
    	return (n==-1 ? -1: 0);
    }
    Pourquoi des MAX_IO et des 2048 ? C'est pas cohérent...

    Pour tester ton code plus sérieusement, il faudrait une requête HTTP valide.

  10. #10
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Pourquoi des MAX_IO et des 2048 ? C'est pas cohérent...

    Pour tester ton code plus sérieusement, il faudrait une requête HTTP valide.
    MAX_IO est égal à 4096 dans mon programme.

    J'ai mi une plus grosse taille que 2048 pour éviter d'avoir à realloc à chaque boucle mais sans allouer trop de mémoire. (Peux être que mon raisonnement est mauvais).

    Je vais simplifier mon programme et le rentre opérationnel et je post ça.
    Merci de votre aide

Discussions similaires

  1. fuite de mémoire ?
    Par salseropom dans le forum C
    Réponses: 2
    Dernier message: 12/01/2006, 16h19
  2. Réponses: 1
    Dernier message: 02/12/2005, 14h18
  3. fuite de mémoire
    Par mamag dans le forum MFC
    Réponses: 17
    Dernier message: 19/08/2005, 10h42
  4. Fuite de mémoire en utilisant le template list
    Par schtroumpf_farceur dans le forum Langage
    Réponses: 9
    Dernier message: 18/07/2005, 20h44
  5. Réponses: 8
    Dernier message: 17/10/2002, 12h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo