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 :

Plantage lors d'un free


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut Plantage lors d'un free


    J'ai un petit soucis de la libération d'une chaîne avec free(). Le code devenant vraiment très gros les erreurs potentiels les plus banale peuvent se glisser dedans mais là je vois pas trop, je vais vous montrer ce que je peut pour pas trop vous embrouiller

    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
    DECLSPEC void b_string_free (BString ** p_str)
    {
       if (p_str && *p_str)
       {
          b_object_unref (p_str);
    
          if ((*p_str)->sz_string)
          {
             b_free ((*p_str)->sz_string);
             (*p_str)->sz_string = NULL;
          }
    
          b_free (*p_str);
          *p_str = NULL;
       }
    }
    Cette ligne pose problème, l'objet est créé ainsi (je vais vous montrer une partie du cheminement dans l'ordre) :
    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
    DECLSPEC BString * b_string_new_with_text (const char * s_str)
    {
       BString * p_new = NULL;
     
       if (s_str)
       {
          p_new = b_string_new ();
     
          if (p_new)
          {
             p_new->sz_string = b_string_dup (s_str);
     
             if (p_new->sz_string)
                p_new->len = strlen (p_new->sz_string);
             else
                b_string_free (&p_new);
          }
       }
     
       return p_new;
    }
    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
    DECLSPEC BString * b_string_new (void)
    {
       BString * p_new = b_malloc (sizeof (* p_new));
     
       if (p_new)
       {
          b_object_initializer (
             p_new,
             B_STRING_TYPE,
             B_STRING_TYPE,
             B_OBJECT_REFERENCEABLE);
     
          p_new->len              = 0;
          p_new->sz_string        = NULL;
     
          p_new->destroy_func     = b_string_free;
     
          b_object_ref ((BObject **)&p_new);
       }
     
       return p_new;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    static char * b_string_dup (const char * s_str)
    {
       char * s = NULL;
     
       if (s_str)
       {
          s = b_malloc (strlen (s_str) + 1);
     
          if (s)
             strcpy (s, s_str);
       }
     
       return s;
    }
    Si jamais vous voyez une anomalie quelque part...

    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 499
    Par défaut
    Hello,

    Il nous manque des infos. J'imagine que la ligne en rouge est celle où le plantage se produit. Cela dit, il nous faudrait la déclaration de « BString » ainsi que la fonction « b_free() ».

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Si tu veux mais ca ne te sera surement d'aucune utilité
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct
    {
       BObject;
     
       char * sz_string;  /* Always null terminated string. */
     
       size_t len;
    }BString;
    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
    /* Opaque structure for Object information. */
    typedef struct _BType BType;
     
    /* The fundamental BLIB Object.
     
       !! ATTENTION !!
       All structure members are private.
     */
    struct _BObject
    {
       /* Private object informations. */
       BType * type;
     
       /* Callback function for auto-destroy. */
       BDestroyCallback destroy_func;
     
       /* Reserved pointers for futur. */
       void * p_reserved_1;
       void * p_reserved_2;
       void * p_reserved_3;
     
       /* Chaining for all objects. */
       struct _BObject * p_prev;
       struct _BObject * p_next;
    };
    Le type opaque BType si déjà on y est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* Opaque structure for Object information. */
    struct _BType
    {
       char * s_object_name;   /* BObject name, ex: MyObject_1 */
       char * s_object_type;   /* BObject type, ex: BObject, BWidget, ... */
     
       /* Determine if the object is referenced to the garbage collector or
          if itself refence like a list node. The garbage collector refenrece
          counter is always update because it's still an object that is running
          in memory. */
       BLib_bool is_gc_referenceable;
    };
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    DECLSPEC void * b_malloc (size_t size)
    {
    #ifdef BLIB_MEM_TRACE
       void * p = malloc (size);
     
       if (b_flag_trace_get ())
          b_mem_trace_add_comment (p, &BLib_mem_info, MALLOC_PTR);
     
       return p;
    #else
       return malloc (size);
    #endif // BLIB_MEM_TRACE
    }
     
     
    DECLSPEC void * b_calloc (size_t nmemb, size_t size)
    {
    #ifdef BLIB_MEM_TRACE
       void * p = calloc (nmemb, size);
     
       if (b_flag_trace_get ())
          b_mem_trace_add_comment (p, &BLib_mem_info, CALLOC_PTR);
     
       return p;
    #else
       return calloc (nmemb, size);
    #endif // BLIB_MEM_TRACE
    }
     
     
    DECLSPEC void * b_realloc (void * ptr, size_t size)
    {
    #ifdef BLIB_MEM_TRACE
       void * p = realloc (ptr, size);
     
       if (b_flag_trace_get ())
          b_mem_trace_add_comment (p, &BLib_mem_info, REALLOC_PTR);
     
       return p;
    #else
       return realloc (ptr, size);
    #endif // BLIB_MEM_TRACE
    }
     
     
    DECLSPEC void  b_free (void * ptr)
    {
    #ifdef BLIB_MEM_TRACE
       if (b_flag_trace_get ())
          b_mem_trace_add_comment (ptr, &BLib_mem_info, FREE_PTR);
    #endif // BLIB_MEM_TRACE
     
       free (ptr);
    }
    Par ailleurs, j'ai testé la chaîne avec un printf juste avant le free est la chaîne apparait correctement... Moi je vois pas d'autant plus que je libère d'autres chaînes bien avant celle-ci et ca fonctionne sans soucis
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  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
    Je ne sais pas si c'est une anomalie, ne connaissant pas la fonction b_object_ref() ni ce qu'elle fait :
    Dans la fonction b_string_new() : b_object_ref ((BObject **)&p_new);.
    On transmet l'adresse d'une variable locale à la fonction. Je ne sais ce que la fonction b_object_ref() fait de cette donnée (stocke t-elle cette adresse ?) , mais cette donnée sera inutilisable en sortie de la fonction b_string_new().

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    b_object_ref (BOboject ** p_obj); enregistre l'adresse de l'objet passé en paramètre dans une liste du même type vu que les objets sont auto liés entre eux mais elle ne fait rien de plus. Le cast que j'ai fait c'est surtout pour que le compilateur n'est rien à dire

    Pour ma part, l'allocation se passe bien, j'accède à la chaîne sans problème, dans mes tests je travaille même dessus pour tester les diverses fonctions et pas de problème.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  6. #6
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Juste comme ça, la fonction b_free() c'est l'equivalent d'un free()?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
             b_free ((*p_str)->sz_string);
             (*p_str)->sz_string = NULL;
    Parce que tu le liberes en premiere ligne et tu veux lui assigner la valeur NULL alors qu'elle n'est plus censé exister?

    Bon je dis ça mais je ne pense vraiment pas avoir ton niveau vu ce que tu nous as déjà programmé

  7. #7
    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
    Citation Envoyé par Franck.H Voir le message
    b_object_ref (BOboject ** p_obj); enregistre l'adresse de l'objet passé en paramètre dans une liste du même type vu que les objets sont auto liés entre eux mais elle ne fait rien de plus. Le cast que j'ai fait c'est surtout pour que le compilateur n'est rien à dire
    ...
    C'est la question que je pose : est-ce que ce qui sera enregistré dans la liste par cette fonction sera p_obj ou *p_obj, parce si c'est le premier cas, on aura , dans le cas cité, des problèmes si on utilise cette adresse à un moment quelconque.

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

Discussions similaires

  1. [Système] Plantage lors du login
    Par yvon_huynh dans le forum Langage
    Réponses: 7
    Dernier message: 28/08/2006, 16h27
  2. Réponses: 5
    Dernier message: 26/07/2006, 10h52
  3. Réponses: 22
    Dernier message: 28/03/2006, 14h59
  4. plantage lors de mon free
    Par salseropom dans le forum C
    Réponses: 16
    Dernier message: 17/02/2006, 18h43
  5. plantage lors de réception de fihier
    Par marsupile dans le forum C++Builder
    Réponses: 9
    Dernier message: 22/01/2004, 18h08

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