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 :

[VC++2005] malloc et realloc


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut [VC++2005] malloc et realloc
    Bonjour ,

    dans la portion de code 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
    16
    17
    18
    19
     
    struct KprotoPckt{
      uint8_t	Type;				// Type de trame
      uint16_t	Checksum;			// Reçue du Réseau
      uint16_t	DataLength;			// Reçue du Réseau
      uint8_t	Serial[SERIAL_NUMBER_LENGTH];	// Numéro de série du produit
      uint8_t	*Data;				// Les données transportées
    };
     
     if(KprotoPckt->Data)
    	      KprotoPckt->Data=realloc(KprotoPckt->Data,KprotoPckt->DataLength * sizeof(uint8_t *));
    	    else
    	      KprotoPckt->Data=malloc(KprotoPckt->DataLength * sizeof(uint8_t *));
     
    	    if(KprotoPckt->Data == NULL){
    	      datation(); printf("Error: can't allocate memory for a RX packet !!! \n");
    		  free(KprotoPckt->Data);
    	      return;
    	    }
    j'ai un plantage au niveau du realloc => Errreur allocation de memoire

    Je libere bien la memoire apres traitemement comme ce-ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     if(KprotoPckt.Data != NULL){
        free(KprotoPckt.Data);
        KprotoPckt.Data=NULL;
      }
    d'ou peux provenir le probleme ?
    est ce une incompatibilite de mon systeme ? je suis sur XP ?
    J'utilise Visual Studio 2005, peut etre qu'il existe une directive de compilation pour eviter cela ?
    que veux dire le message exactement ? est ce que ca veut dire qu'il n'arrive plus a allouer du tas au niveau memoire ?
    est ce au niveau de la memoire vive?
    Est ce un probleme de cadrage au niveau memoire ?
    j'ai 2go de ram.

    Merci de votre aide.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Bonjour,
    1. Tu n'es pas obligé de faire ton test pour malloc/realloc : La norme dit que realloc(NULL, ...) doit se comporter comme malloc(...).
    2. Pareil pour le free: La norme dit que free(NULL) ne doit pas planter.
    3. Que veux-tu dire exactement par "plantage au niveau du realloc => Errreur allocation de memoire" ?
    4. Vérifie que DataLength possède une valeur correcte.
    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
    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 andromeda Voir le message
    dans la portion de code suivante:
    Ton code est incomplet. J'ai fait quelques hypothèses. Ce code fonctionne :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
     
    #define SERIAL_NUMBER_LENGTH 32
     
    struct KprotoPckt
    {
       uint8_t Type;                // Type de trame
       uint16_t Checksum;           // Reçue du Réseau
       uint16_t DataLength;         // Reçue du Réseau
       uint8_t Serial[SERIAL_NUMBER_LENGTH]; // Numéro de série du produit
       uint8_t *Data;               // Les données transportées
    };
     
    void datation (void)
    {
       puts ("datation");
    }
     
    static void f (struct KprotoPckt *KprotoPckt)
    {
       if (KprotoPckt->Data)
          KprotoPckt->Data =
             realloc (KprotoPckt->Data,
                      KprotoPckt->DataLength * sizeof (uint8_t *));
       else
          KprotoPckt->Data = malloc (KprotoPckt->DataLength * sizeof (uint8_t *));
     
       if (KprotoPckt->Data == NULL)
       {
          datation ();
          printf ("Error: can't allocate memory for a RX packet !!! \n");
          free (KprotoPckt->Data);
          return;
       }
    }
     
    int main (void)
    {
       struct KprotoPckt KprotoPckt = { 0, 0, 0, {0}, 0 };
       f (&KprotoPckt);
     
       if (KprotoPckt.Data != NULL)
       {
          free (KprotoPckt.Data);
          KprotoPckt.Data = NULL;
       }
     
       return 0;
    }
    Mais comme l'a très justement signalé Medinoc, il est inutilement complexe...
    Ceci est suffisant :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
     
    #define SERIAL_NUMBER_LENGTH 32
     
    struct KprotoPckt
    {
       uint8_t Type;                // Type de trame
       uint16_t Checksum;           // Reçue du Réseau
       uint16_t DataLength;         // Reçue du Réseau
       uint8_t Serial[SERIAL_NUMBER_LENGTH]; // Numéro de série du produit
       uint8_t *Data;               // Les données transportées
    };
     
    void datation (void)
    {
       puts ("datation");
    }
     
    static void f (struct KprotoPckt *KprotoPckt)
    {
       KprotoPckt->Data =
          realloc (KprotoPckt->Data,
                   KprotoPckt->DataLength * sizeof *KprotoPckt->Data);
     
       if (KprotoPckt->Data == NULL)
       {
          datation ();
          printf ("Error: can't allocate memory for a RX packet !!! \n");
          return;
       }
    }
     
    int main (void)
    {
       struct KprotoPckt KprotoPckt = { 1, 0, 128, {1234}, NULL };
       f (&KprotoPckt);
     
       free (KprotoPckt.Data), KprotoPckt.Data = NULL;
     
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    tu veux dire qu'il n'y a pas besoin de tester si c'est egal a null, c'est bien ca ?
    je pensais qu'il fallait le faire, dans les doc il verifie toujours avant de poursuivre si le pointeur allouer est == a null.

    ben en fait l'erreur, c'est une aerreur d'allocation memoir, donc en gros le realloc plante et mon programme plante.

    apres verification datalength a l'air correct.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 376
    Points : 41 544
    Points
    41 544
    Par défaut
    andromeda: Et si tu exécutes dans le debugger, n'as-tu pas plus d'information sur l'erreur ?
    Un truc du genre "Damage after normal block blabla blabla" par exemple, indique qu'il y a eu débordement de tableau avant le realloc ou free...
    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.

  6. #6
    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 andromeda Voir le message
    ben en fait l'erreur, c'est une aerreur d'allocation memoir, donc en gros le realloc plante et mon programme plante.

    apres verification datalength a l'air correct.
    Tu n'as pas indiqué comment tu appelais la fonction. Je suppose que les données de la structure ne sont pas initialisées, d'où le crash avec realloc() à cause de la valeur indéterminée de data. Je rappelle que le premier paramètre de realloc() doit impérativement être :
    • NULL ou
    • une valeur retournée par un malloc(), realloc() ou calloc().
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    en reverifiant, la valeur de datalength est egal a 0, c'est peut etre ca.

    met ca ne devrait pas planter je pense, car un realloc de 0 doit me garder l'allocation precedente.

    je m'explique:

    si j'avais allouer precedemment un tableu de 5 char par exemple avec malloc

    j'ai tab[5]

    si je realloue avec realloc et que la valeur de la reallocation est egal 0, je devrais toujours avoir mon tableau de 5 char ?

    c'est une question , car j'ai des doute.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    j'ai oublie de repondre a ton message precedent

    au debut du programme j'initialise ma structure avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    memset(&KprotoPckt,0,sizeof(KprotoPckt));
    je ne comprend pas tres bien ta question

    Je rappelle que le premier paramètre de realloc() doit impérativement être :

    * NULL
    * une valeur retournée par un malloc(), realloc() ou calloc().

    tu veux dire que je dois faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (KprotoPckt->Data)
          KprotoPckt->Data =
             realloc (NULL,
                      KprotoPckt->DataLength * sizeof (uint8_t *));
       else
          KprotoPckt->Data = malloc (KprotoPckt->DataLength * sizeof (uint8_t *));
    donc de remplacer KprotoPckt->Data par NULL dans le realloc ?

    Merci de ton aide

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Je pense que tu fais bien d'avoir des doutes, car à mon avis, realloc(..., 0) se comporte comme malloc(0) : Alloue un bloc de taille nulle...
    Edit2: Ah non c'est encore pire: realloc(..., 0) libère la mémoire (du moins, c'est le cas sous VS2005).
    Edit3: Et Visual suit le comportement standard.

    Edit pour ta dernière question : Non. L'important est que le pointeur KprotoPckt->Data ne soit modifié que par un malloc() ou un realloc().

    Et supprime ton memset(). Utilise une initialisation avec ={0} à 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.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Au passage, donner le même nom à une structure est une variable, cay mal...
    struct KprotoPckt KprotoPckt = {0}
     
    ...
     
    + La fonction f() d'Emmanuel...
    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.

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Au passage, donner le même nom à une structure est une variable, cay mal...
    struct KprotoPckt KprotoPckt = {0}
     
    ...
     
    + La fonction f() d'Emmanuel...
    j'ai renome autrement ma fonction et initialiser correctement comme tu as dit plus haut.

    donc en gros mon probleme viendrais de la valeur 0 du realloc ?
    car si ca libere la memoire, en effet ca retourne null.

    Merci.

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 137
    Points
    137
    Par défaut
    en fait maintenant ca marche:

    j'ai fait ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    KprotoPckt->Data = NULL;
    KprotoPckt->Data = malloc (KprotoPckt->DataLength * sizeof (uint8_t *));
    car c'est appele dans une boucle.

    concernant la valeur de retour 0 c'est normale pour mon traitement, je ne test donc pas la valeur NULL de l'allocation, comme ca la libere l'allocation memoire de toute facon quand c'est egal a zero.

    maintenant tout marche bien.

    Merci de m'avoir aider.

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

Discussions similaires

  1. Embrouille avec les malloc / calloc / realloc
    Par titimoi dans le forum Débuter
    Réponses: 16
    Dernier message: 12/03/2009, 16h53
  2. Problème dans le malloc et realloc
    Par ricomix2 dans le forum C
    Réponses: 6
    Dernier message: 08/03/2008, 07h54
  3. malloc et realloc
    Par dot-_-net dans le forum Bibliothèque standard
    Réponses: 8
    Dernier message: 21/01/2008, 08h40
  4. malloc calloc realloc free
    Par lia20 dans le forum C
    Réponses: 7
    Dernier message: 26/05/2007, 15h22
  5. Malloc et realloc
    Par Triomen dans le forum C
    Réponses: 6
    Dernier message: 21/02/2005, 19h20

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