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

 C Discussion :

realloc erreur avec valgrind


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut realloc erreur avec valgrind
    salut,
    en utilisant valgrid sur ce 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
        char buffer[BUFF+1];
        memset(buffer,0,sizeof(buffer));
     
        char *HtmlContent = (char *)malloc(sizeof(char)+1);
     
        sprintf(HtmlContent," ");
       unsigned long long int total = 0;
     
        while((res = recv(sock,buffer,BUFSIZ,0))>0)
        {
     
            if(res>0)
            {
                total+=res;
            //  printf("res = %d ,total = %Ld\n",res,total);    
                if ((size>0)&&(total>size))
                    break;
                HtmlContent = (char *)realloc(HtmlContent,sizeof(char)*(total+1));
                if(HtmlContent == NULL)
                {
                    free(server);
                    close(sock);
                    return NULL;
                }
                strcat(HtmlContent,buffer);
            }
            memset(buffer,0,res);
        }
    et l'erreur:
    Address 0x4e47584 is 0 bytes after a block of size 2,948 alloc'd
    ==23331== at 0x4A06129: realloc (vg_replace_malloc.c:525)
    ==23331== by 0x4C0D55E: getHTTPInfo (www.c:428)
    ==23331== by 0x40092F: main (content.c:14)
    et encore celle ci:
    ==24629== Invalid write of size 1
    ==24629== at 0x4A065DF: strcat (mc_replace_strmem.c:176)
    ==24629== by 0x4C0D5A3: getHTTPInfo (www.c:435)
    j'ai beau lire et relire je ne vois pas ce qui cloche. quelqu'un pourait-il m'aider un tout petit peu? merci

    je precise que le code marche 9/10, la seule fois ou il plante c'est justement au niveau de realloc.

  2. #2
    Membre émérite
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Par défaut
    Bonjour,

    Je pense qu'il y a une petite erreur sur le realloc. Dans le man realloc il précise sur le retour de la fonction,
    Citation Envoyé par man realloc
    realloc() renvoie un pointeur sur la mémoire nouvellement allouée, qui est correctement alignée pour n'importe quel type de variable, et qui peut être différent de ptr, ou NULL si la demande échoue, ou si size vaut zéro. Si realloc() échoue, le bloc mémoire original reste intact, il n'est ni libéré ni déplacé.
    Donc je pense que lors du realloc, il faut utiliser une autre variable pour tester son retour.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char *HtmlContentProv = NULL ;
     
    HtmlContentProv = (char *)realloc(HtmlContent,sizeof(char)*(total+1)) ;
    if(HtmlContentProv==NULL) {
        free(HtmlContent) ;     // Libère la mémoire déjà allouée
        free(server) ;
        close(sock) ;
        return NULL ;
    }
    // Récupération de la mémoire nouvellement allouée
    HtmlContent = HtmlContentProv ;
    ...
    La fonction strcat ajoute la chaîne src à la fin de la chaîne dest et cela jusqu'à trouver le \0 de dest. Es-tu sûr que la fonction recv ajoute un \0 dans ta variable buffer ?
    Le fonction strcat s'arrêtera si, et seulement si elle trouve un \0 dans buffer. S'il y en a pas au bout de BUFSIZ caractères, strcat va continuer à écrire dans une zone mémoire "non allouée" jusqu'à plus de mémoire ou pire.

    Au mieu, ajoute un \0 dans ton buffer après réception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char buffer[BUFSIZ+2];
    // après recv()
    buffer[res+1] = 0 ;
    Sinon tu peux utiliser la fonction strncat et ajouter un \0 manuellement après la concaténation des 2 buffers.

  3. #3
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut
    bon j'ai modifier comme tu m'as dit, et aussi dans le man realloc comme on dit que si ptr=NULL c'est equivalent a malloc, alors j'ai vire le malloc(1) du debut. ca donne ca:
    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
     char *HtmlContent = NULL;//(char *)malloc(sizeof(char)+1);
    //  sprintf(HtmlContent," ");
        unsigned long long int total = 0;
     
        while((res = recv(sock,buffer,BUFSIZ,0))>0)
        {
     
            if(res>0)
            {
                buffer[res+1] = '\0';
                total+=res;
            //  printf("res = %d ,total = %Ld\n",res,total);    
                if ((size>0)&&(total>size))
                    break;
                char *ptr = (char *)realloc(HtmlContent,sizeof(char)*(total+1));
                if(ptr == NULL)
                {
                    break;
                }
                HtmlContent = ptr;
                strcat(HtmlContent,buffer);
            }
            memset(buffer,0,res);
    }
    bon j'ai mit break, au lieu du return pour conserver l'anciene valeur de HtmlContent.
    Et je susi passe de 4 erreurs a une qui en faite ressemble beaucoup a l'ancienne:
    ==24829== Conditional jump or move depends on uninitialised value(s)
    ==24829== at 0x4A065AA: strcat (mc_replace_strmem.c:176)
    ==24829== by 0x4C0D593: getHTTPInfo (www.c:435)
    ==24829== by 0x4007B7: main (in /home/alain/codes/tvm/httpc/www/httpget)
    ==24829== Uninitialised value was created by a heap allocation
    ==24829== at 0x4A06031: malloc (vg_replace_malloc.c:236)
    ==24829== by 0x4A060AB: realloc (vg_replace_malloc.c:525)
    ==24829== by 0x4C0D56A: getHTTPInfo (www.c:429)
    ==24829== by 0x4007B7: main (in /home/alain/codes/tvm/httpc/www/httpget)

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     char *HtmlContent = NULL;//(char *)malloc(sizeof(char)+1);
    ....
                char *ptr = (char *)realloc(HtmlContent,sizeof(char)*(total+1));
    ....
                HtmlContent = ptr;
                strcat(HtmlContent,buffer);
    Au départ, HtmlContent ==NULL et le realloc() agit comme un malloc. Il alloue de la mémoire qui n'est pas initialisée et contient donc n'importe quoi.
    strcat() ajoute alors quelque chose (buffer) à n'importe quoi et on obtient ... n'importe quoi. Ce qui est signalé par valgrind.

    Il faut initialiser la première fois le premier élément du buffer alloué par le realloc() avec '\0' en utilisant strcat() ou utiliser strcpy()

  5. #5
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut
    justement le probleme est entier. si tu regardes dans le post d'avant j'avais un malloc suivit de sprintf(HtmlContent," "); a ma connaissance sprintf() ajoute '\0' mais j'avais aussi l'erreur de strcat.
    bon je remet l'initialisation tout de meme.
    ....
    j'ai tester avant de cliquer sur envoyer la reponse. en remplacant sprintf par strcpy("\0"); j'ai plus d'erreures

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    justement le probleme est entier. si tu regardes dans le post d'avant j'avais un malloc suivit de sprintf(HtmlContent," "); a ma connaissance sprintf() ajoute '\0' mais j'avais aussi l'erreur de strcat.

    j'ai tester avant de cliquer sur envoyer la reponse. en remplacant sprintf par strcpy("\0"); j'ai plus d'erreures
    Oui, c'est normal. Dès le départ, tu remplis ta chaine avec un caractère alors qu'elle est censée n'en contenir aucun :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *HtmlContent = malloc(sizeof(char)+1);
    sprintf(HtmlContent," "); <-- hop, un caractère dans la chaine (suivi d'un '\0' mais c'est pas le problème ici)
    unsigned long long int total = 0; <-- ... et pourtant on considère qu'il n'y en a pas.
    Du coup :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while((res = recv(sock,buffer,BUFSIZ,0))>0)
    {
    ...
       total+=res;
    ...
       char *ptr = (char *)realloc(HtmlContent,sizeof(char)*(total+1));
    ...
       HtmlContent = ptr;
       strcat(HtmlContent,buffer); <-- BOUM ! "HtmlContent" contient déjà 1 caractère ! On rajoute la chaine "buffer", de taille "res", suivi d'un '\0'. Au 1er passage de la boucle, la chaine a donc un total de 1+"res"+1. Or, on n'a alloué que "total"+1 pour HtmlContent, soit 0+"res"+1.
    }
    --------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char buffer[BUFF+1];
    ...
    while((res = recv(sock,buffer,BUFSIZ,0))>0)
    Bof, pas terrible...

    -------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       total+=res;
    ...
       char *ptr = (char *)realloc(HtmlContent,sizeof(char)*(total+1));
       if(ptr == NULL)
       {
          break;
       }
    Si realloc échoue, la taille de ta chaine est trop longue, vu que tu modifie "total" avant... Risque de crash plus loin.

    -------------

    Inutile : la condition est toujours vraie.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur avec procédure LockWorkStation ...
    Par simonseztech dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 16/08/2004, 15h33
  2. [Débutant][Conception] Erreur avec une classe interne
    Par Devil Redneck dans le forum Général Java
    Réponses: 5
    Dernier message: 11/06/2004, 15h45
  3. Erreur avec les ADO
    Par megane dans le forum Bases de données
    Réponses: 7
    Dernier message: 08/03/2004, 21h37
  4. Erreur avec WM_COMMAND (BN_CLICKED)
    Par cyberlewis dans le forum Windows
    Réponses: 2
    Dernier message: 09/02/2004, 00h25
  5. probleme avec valgrind
    Par bloops dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 26/11/2003, 22h49

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