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

  1. #1
    Membre confirmé
    Homme Profil pro
    Etudiant administrateur systèmes et réseaux
    Inscrit en
    octobre 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Etudiant administrateur systèmes et réseaux

    Informations forums :
    Inscription : octobre 2007
    Messages : 707
    Points : 460
    Points
    460

    Par défaut Fuite mémoire ou faux positif ?

    Hello,

    Je sollicite votre aide pour corriger une fuite mémoire dont je n'arrive pas à déterminer l'origine.
    Il s'agit peut être d'un faux positif mais ne sachant répondre à mon interrogation tout seul comme un grand, me voici.

    J'ai le main suivant :

    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
     
    int main()
    {
        f_log = NULL;
        if ( ( f_log = log_create_null() ) )
        {
            srand(time(NULL));
     
            i_2D_t* st = NULL;
            size_t* y = NULL;
            if ( ( st = i_2D_create_random( 10, &y, 9, 9999, 2) ) ) // Créer un tableau 2D d'entiers positifs ou negatifs (2) et compris entre 0 et 9999 comportant 10 lignes de taille variable ( 0-9 cases )
            {
                i_2D_line_add( st, 9 ); //Supprimer la dernière ligne du tableau 2D
                i_2D_display( st );
                i_2D_detroy( st );
            }
            log_display( f_log );
            log_destroy( f_log );
        }
        return 0;
    }
    Lorsque j'appelle cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    i_2D_line_add( st, 9 ); //Supprimer la dernière ligne du tableau 2D
    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
    void i_2D_line_add_( int*** p, size_t* x, size_t x_new, size_t** y )
    {
        int** p_realloc = NULL;
        if ( ( p_realloc = realloc( (*p), x_new*sizeof( **p ) ) ) )
        {
            *p = p_realloc;
            for ( size_t i=*x ; i<x_new ; i++ )
                 (*p)[i] = NULL;
     
            size_t* y_realloc = NULL;
            if ( ( y_realloc = realloc( (*y), x_new*sizeof( **y ) ) ) )
            {
                (*y) = y_realloc;
                for ( size_t i=*x; i<x_new ; i++ )
                    (*y)[i] = 0;
     
                *x = x_new;
            }
        }
    }
    Dr Memory détecte cette erreur (#2), sachant que le nombre d'octets en fuite ( 20 ici ) est variable d'une exécution à l'autre.
    Error #1: REACHABLE LEAK 8 direct bytes 0x03360178-0x03360180 + 0 indirect bytes
    <memory was allocated before tool took control>

    Error #2: LEAK 20 direct bytes 0x03360428-0x0336043c + 0 indirect bytes
    # 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2577]
    # 1 i_allocate [D:/#SORT/Z05_CODE_SOURCE/ptr.c:11]
    # 2 i_2D_allocate_random_ [D:/#SORT/Z05_CODE_SOURCE/ptr.c:1089]
    # 3 i_2D_create_random [D:/#SORT/Z05_CODE_SOURCE/ptr.c:1171]
    # 4 main [D:/#SORT/Z05_CODE_SOURCE/main.c:44]

    ===========================================================================
    FINAL SUMMARY:

    DUPLICATE ERROR COUNTS:

    SUPPRESSIONS USED:

    ERRORS FOUND:
    0 unique, 0 total unaddressable access(es)
    0 unique, 0 total uninitialized access(es)
    0 unique, 0 total invalid heap argument(s)
    0 unique, 0 total GDI usage error(s)
    0 unique, 0 total handle leak(s)
    0 unique, 0 total warning(s)
    1 unique, 1 total, 20 byte(s) of leak(s)
    0 unique, 0 total, 0 byte(s) of possible leak(s)
    1 unique, 1 total, 8 byte(s) of still-reachable allocation(s)
    NO ERRORS IGNORED
    Je suppose donc que c'est cette fonction qui est la cause de cette fuite.
    Si j'ajoute une ligne au tableau 2D plutôt que d'en supprimer une, je n'ai pas cette erreur.
    realloc, libère bien la mémoire si la nouvelle taille est inférieure à l'originale ?
    Je ne vois que cette possibilité actuellement.

    Merci d'avance.
    Cordialement.
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

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

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 942
    Points : 39 908
    Points
    39 908

    Par défaut

    Je ne vois pas de code, dans le cas où x_new est inférieur à *x, pour libérer les lignes qui ne sont plus référencées par le tableau de pointeurs.
    (et pour éviter de laisser ta matrice dans un état instable si l'allocation échoue, tu vas devoir copier ces pointeurs dans un nouveau tableau avant de faire le realloc()... auquel point tu as plus vite fait d'allouer systématiquement un nouveau tableau de pointeurs à la place).
    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.

  3. #3
    Expert éminent sénior

    Profil pro
    Développeur informatique
    Inscrit en
    novembre 2006
    Messages
    6 810
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2006
    Messages : 6 810
    Points : 14 247
    Points
    14 247

    Par défaut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if ( ( y_realloc = realloc( (*y), x_new*sizeof( **y ) ) ) )
            {
                (*y) = y_realloc;
                for ( size_t i=*x; i<x_new ; i++ )
                    (*y)[i] = 0;
     
                *x = x_new;
            }
    sauf erreur de ma part,x est affecté mais je ne vois pas où le pointeur est alloué.

    Et puis je sais que c'est le forum C mais perso là c'est du temps perdu tu devrais utiliser des conteneurs C++ ou bien des listes chainées.
    Ce dont on ne peut parler il faut le taire ( Wittgenstein )

  4. #4
    Membre confirmé
    Homme Profil pro
    Etudiant administrateur systèmes et réseaux
    Inscrit en
    octobre 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Etudiant administrateur systèmes et réseaux

    Informations forums :
    Inscription : octobre 2007
    Messages : 707
    Points : 460
    Points
    460

    Par défaut

    Et puis je sais que c'est le forum C mais perso là c'est du temps perdu tu devrais utiliser des conteneurs C++ ou bien des listes chainées.
    C'est un entier passé par adresse. Je ne sais pas si ça répond à ta première interrogation.
    Concernant la deuxième, ce n'est pas du temps de perdu, la preuve je fais encore des erreurs sur des basiques.
    Les listes chainées oui, après je veux juste pratiquer. Je ne cherche pas nécessairement la facilité ou le plus rationnel.

    Citation Envoyé par Médinoc Voir le message
    Je ne vois pas de code, dans le cas où x_new est inférieur à *x, pour libérer les lignes qui ne sont plus référencées par le tableau de pointeurs.
    (et pour éviter de laisser ta matrice dans un état instable si l'allocation échoue, tu vas devoir copier ces pointeurs dans un nouveau tableau avant de faire le realloc()... auquel point tu as plus vite fait d'allouer systématiquement un nouveau tableau de pointeurs à la place).
    Ok merci tu confirmes mes doutes, c'est bien ce qu'il me semblait alors déréférencement suite à réduction du nombre de lignes sur le tableau 2D.

    J'ai modifié de la sorte suite à tes remarques et je ne constate plus la fuite. Cela ne valide pas que ce soit réellement fonctionnel mais ça semble aller dans le bon sens.
    Confirmes tu ?

    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
    void i_2D_line_add_( int*** p, size_t* x, size_t x_new, size_t** y )
    {
        int** p_realloc = NULL;
        if ( *x < x_new )
        {
            if ( ( p_realloc = realloc( (*p), x_new*sizeof( **p ) ) ) )
            {
                for ( size_t i=*x ; i<x_new ; i++ )
                     p_realloc[i] = NULL;
     
                size_t* y_realloc = NULL;
                if ( ( y_realloc = realloc( (*y), x_new*sizeof( **y ) ) ) )
                {
                    for ( size_t i=*x; i<x_new ; i++ )
                        y_realloc[i] = 0;
     
                    *y = y_realloc;
                    *p = p_realloc;
                    *x = x_new;
                }
            }
        }
        if ( *x > x_new )
        {
            p_realloc = *p;
            for ( size_t i=x_new ; i<*x ; i++ )
                free( p_realloc[i] );
     
            if ( ( p_realloc = realloc( p_realloc, x_new*sizeof( *p_realloc ) ) ) )
            {
                size_t* y_realloc = NULL;
                if ( ( y_realloc = realloc( (*y), x_new*sizeof( **y ) ) ) )
                {
                    *y = y_realloc;
                    *p = p_realloc;
                    *x = x_new;
                }
            }
        }
    }
    Petite question subsidiaire : dans le cas de ce que je crois qu'on appelle une surcharge de fonction, il est préférable de faire le contrôle des paramètres dans la fonction f ou f' ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void f(...)
    {
         f'(...);
    }
    UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :

Discussions similaires

  1. [tomcat][memoire] java.net.URL et fuite mémoire
    Par Seiya dans le forum Tomcat et TomEE
    Réponses: 6
    Dernier message: 09/03/2009, 10h41
  2. [Fuites mémoire] Je cherche un utilitaire
    Par 10_GOTO_10 dans le forum C++Builder
    Réponses: 8
    Dernier message: 10/02/2005, 10h03
  3. Outil de recherche de fuite mémoire
    Par eag35 dans le forum MFC
    Réponses: 4
    Dernier message: 02/02/2005, 12h46
  4. [SWT]SWT et fuite mémoire(ou pas)
    Par menuge dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 22/06/2004, 21h40
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 17h20

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