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 :

* glibc detected * free(): invalid pointer


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Février 2006
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 102
    Points : 68
    Points
    68
    Par défaut * glibc detected * free(): invalid pointer
    Bonjour,


    Je rencontre quelques petits soucis, lorsque je veux appeler free() sur un pointeur, pointant le résultat d'une requête SQL via une structure. La structure est la suivante, elle correspond à une colonne de résultat SQL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
      char ColName[ORA_COLNAME_MAX];    /* Name of the ORACLE column */
      int ColLen;			    /* Max length of the values */
      char *Values;			    /* Array of Values (see SQL_Query) */
    } SqlQuery;
    typedef SqlQuery * SqlQueryPtr;
    J'ai ma fonction exécutant ma requête SQL, qui me renvoie le nombre d'enregistrements affectés et pointeur de SqlQueryPtr (plusieurs colonnes retournées). Jusque la tout va bien, les résultats sont accessibles, c'est parfait.

    A la fin du programme, lorsque je veux libérer mon pointeur de SqlQueryPtr, et qu'il n'y a qu'un seul enregistrement retourné j'ai cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *** glibc detected *** free(): invalid pointer: 0x081fb400 ***
    et plus loin celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *** glibc detected *** double free or corruption (!prev): 0x081fb3a0 ***
    Le programme se termine normallement ... La fonction censait libérer la mémoire est la suivante :

    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
     
    void SQL_FreeQuery (SqlQueryPtr query){
        unsigned int    i = 0;
        trace()
        if (query != NULL) {
            while( i < 2 ){
                printf("-> %p (%s)\n",query[i].Values,query[i].Values);
                free(query[i].Values);
                i++;
            }
            trace()
            free(query);
            query = NULL;
        }
    }
    Le 2 en dur est normal, c'est un autre problème, il correspond au nombre de champs du résultat

    Je l'appelle de la manière suivante dans le programme principal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SqlQueryPtr SQP;
     
    /* Exécution de la requete */
    SQL_Query("SELECT champ1, champ2 FROM matable",&SQP,0,BOOL_FALSE);
     
    /* Libération du résultat de la requête */
    SQL_FreeQuery(SQP);
    Lors de l'exécution le printf vaut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    -> 0x81fb400 (pierre)
    *** glibc detected *** free(): invalid pointer: 0x081fb400 ***
    -> 0x81fb420 (8465)
    *** glibc detected *** double free or corruption (!prev): 0x081fb3a0 ***
    Le "double free" se produit lors du free(query).

    Chose étrange, j'ai ce message d'erreur lorsque un seul tuple est retourné par la requête, avec 2 tuples ou plus je n'ai plus les messages d'erreurs. Pourquoi, n'ai-je le "invalid pointer" que quand i=0, quand i=1 il n'y a pas de message.

    J'espère avoir été clair ...

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par ViRouF
    Je rencontre quelques petits soucis, lorsque je veux appeler free() sur un pointeur, pointant le résultat d'une requête SQL via une structure. La structure est la suivante, elle correspond à une colonne de résultat SQL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
      char ColName[ORA_COLNAME_MAX];    /* Name of the ORACLE column */
      int ColLen;			    /* Max length of the values */
      char *Values;			    /* Array of Values (see SQL_Query) */
    } SqlQuery;
    typedef SqlQuery * SqlQueryPtr;
    J'ai ma fonction exécutant ma requête SQL, qui me renvoie le nombre d'enregistrements affectés et pointeur de SqlQueryPtr (plusieurs colonnes retournées). Jusque la tout va bien, les résultats sont accessibles, c'est parfait.

    A la fin du programme, lorsque je veux libérer mon pointeur de SqlQueryPtr, et qu'il n'y a qu'un seul enregistrement retourné j'ai cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *** glibc detected *** free(): invalid pointer: 0x081fb400 ***
    et plus loin celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *** glibc detected *** double free or corruption (!prev): 0x081fb3a0 ***
    Ce genre d'erreur survient en général suite à un débordement de mémoire allouée. Il y a un bug dans ton code.

    Il y a un pointeur non initialisé dans la structure (char *Values). Qui est chargé de l'initialiser ?
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Membre du Club
    Inscrit en
    Février 2006
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 102
    Points : 68
    Points
    68
    Par défaut
    Alors, pour l'initialisation c'est SQL_Query qui le fait, voilà le 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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    int SQL_Query (const char * query, SqlQueryPtr * finalResult, SqlQueryInputPtr input, BoolEnum noDeleteWarning){
     
     
            SqlQueryPtr	    selectAnswer;
     
     
     
            nbQueryFields = mysql_num_fields(queryResult);
            nbQueryResultRow = mysql_num_rows(queryResult);
     
            selectAnswer = (SqlQueryPtr) _HUGE_ALLOC_( nbQueryResultRow * sizeof(SqlQuery));
            if( selectAnswer == NULL ){
                sprintf(S_ErrorMsg, "SQL_Query: Memory allocation failed");
                S_DisplayError();
                return (-1);
            }
     
            /*
            * Get select-list column names : allocate N entries in selList.
            */
            for(i=0; i<nbQueryFields; i++){
                queryResultField = mysql_fetch_field(queryResult);
                strcpy(selectAnswer[i].ColName, queryResultField->name);
                selectAnswer[i].ColLen = queryResultField->length + 1;
     
                selectAnswer[i].Values = (char*) _HUGE_ALLOC_(nbQueryResultRow * selectAnswer[i].ColLen * sizeof(char));
     
                if( selectAnswer[i].Values == NULL ){
                    sprintf(S_ErrorMsg, "SQL_Query: Memory allocation failed");
                    S_DisplayError();
                    return (-1);
                }
            }
     
            [...]
     
            *finalResult = selectAnswer;
     
            return nbQueryResultRow;
    _HUGE_ALLOC = malloc

  4. #4
    Membre éclairé Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Points : 771
    Points
    771
    Par défaut
    Je n'ai pas tout lu, mais je pense avoir noté quelque chose. Vous allouez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    selectAnswer = (SqlQueryPtr) _HUGE_ALLOC_( nbQueryResultRow * sizeof(SqlQuery));
    Mais dans la boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(i=0; i<nbQueryFields; i++){
     ...
     strcpy(selectAnswer[i].ColName, queryResultField->name);
     ...

  5. #5
    Membre du Club
    Inscrit en
    Février 2006
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 102
    Points : 68
    Points
    68
    Par défaut
    Wahooo, bravo c'est effectivement ça le problème, vu que je faisais des SELECT retournant 2 champs souvent et 2 lignes dans une relation bidon je ne voyais pas le problème !

    Merci beaucoup

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    selectAnswer = (SqlQueryPtr) _HUGE_ALLOC_( nbQueryFields * sizeof(SqlQuery));

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 17/05/2019, 17h27
  2. free(): invalid pointer
    Par scapine dans le forum Qt Creator
    Réponses: 2
    Dernier message: 19/01/2014, 09h57
  3. erreur glibc detected double free or corruption.
    Par Screwt-K dans le forum C++
    Réponses: 1
    Dernier message: 02/07/2007, 16h46
  4. [Debutant]*** glibc detected *** free()
    Par Treuze dans le forum Débuter
    Réponses: 3
    Dernier message: 17/03/2006, 15h34
  5. Réponses: 5
    Dernier message: 04/11/2005, 18h59

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