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 :

récupératio de structure et contenu alloué par malloc


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de MicaelFelix
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    254
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 254
    Par défaut récupératio de structure et contenu alloué par malloc
    Bonjour,

    J'ai une structure de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef 
    struct struct_app1
    {
       char var1;
       int dataSize;
       char *data;
    } struct1;
    Pour placer les données dans la structure je n'ai aucun problème, mais c'est pour les récupérer que j'aimerais avoir de l'aide.

    Comment faire pour récupérer les données (elles me reviennent par un char*)? En regardant sur internet j'ai bien compris qu'apparemment il fallait faire:

    char* varReturned;

    struct1 *myStruct;
    myStruct = (myStruct *) MEM_malloc(sizeof(struct1));
    memcpy(&myStruct, varReturned, sizeof(struct1));

    Ce code devrait fonctionner, mais pour la récupération des données (char *data), comment faire?
    Est-ce que cela sera réservé/rempli automatiquement? J'en doute mais je ne sais pas vraiment comment faire.
    Lorsque la memcpy se fait, comment la copie est effectuée sur les pointeurs sur la variable "data"?

    Si quelqu'un pourrait m'éclairer sur les étapes à faire pour être sur que les données "data" soient présentes.

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par MicaelFelix Voir le message
    Bonjour,

    J'ai une structure de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef 
    struct struct_app1
    {
       char var1;
       int dataSize;
       char *data;
    } struct1;
    Pour placer les données dans la structure je n'ai aucun problème, mais c'est pour les récupérer que j'aimerais avoir de l'aide.

    Comment faire pour récupérer les données (elles me reviennent par un char*)? En regardant sur internet j'ai bien compris qu'apparemment il fallait faire:

    char* varReturned;

    struct1 *myStruct;
    myStruct = (myStruct *) MEM_malloc(sizeof(struct1));
    memcpy(&myStruct, varReturned, sizeof(struct1));

    Ce code devrait fonctionner, mais pour la récupération des données (char *data), comment faire?
    Est-ce que cela sera réservé/rempli automatiquement? J'en doute mais je ne sais pas vraiment comment faire.
    Lorsque la memcpy se fait, comment la copie est effectuée sur les pointeurs sur la variable "data"?

    Si quelqu'un pourrait m'éclairer sur les étapes à faire pour être sur que les données "data" soient présentes.
    Le code qui tu as écrit va surtout planter de manière magnifique

    malloc() renvoie un pointeur sur la zone de mémoire allouée (ou null si l'allocation a échoué). Tu peux typecaster ce pointeur en un type autre, pourvu que la taille allouée et la taille du nouveau type sont compatible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    struct1_app* my = (struct1*)(malloc(sizeof(struct1)));
    my->var1 = 10;
    Par contre, malloc() te renvoie une zone de mémoire non initialisée. Le contenu de *my t'est inconnu, il te faut l'initialiser par toi même. Tu peux effectivement faire un memcpy() (mais pas celui que tu proposes, qui va écraser la mémoire et probablement planter, voire faire des choses plus graves encore).

    Si tu programmes en C++, ce qui semblerait logique sinon tu aurais posté dans le forum C, tu as une autre solution qui est beaucoup plus propre : l'opérateur new. Cet opérateur t'évite les cast, et surtout, peut initialiser la structure - a partir du moment ou cette structure (qui est une classe) défini un constructeur. Dans le cas où tu ne définit pas de constructeur, le compilateur en défini un par défaut qui ne fait rien (et donc qui n'initialise rien ; on l'appelle le constructeur par défaut trivial)

    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
    struct struct1
    { ... };
    
    // note que la syntaxe struct x { ... } y; définit une variable y du type x. 
    
    struct1* my = new struct1; // *my non initialisé (constructeur par défaut trivial appelé)
    delete my; // libération de la mémoire. 
    
    struct struct2
    {
      struct2(int a_, float b_)
      : a(a_), b(b_)
      { }
      int a; 
      float b;
    }
    
    struct2* my2 = new struct2(10, 20.0);
    // my2->a == 10 et my2->b == 20.0
    delete my2; // libération de la mémoire
    Je ne saurais trop te conseiller de lire un livre orienté pour les débutant en C++ histoire d'avoir une compréhension correcte de ce qui se passe. C'est un passage plus ou moins obligé (ce site propose le texte en français de Thinking in C++. Lis le attentivement, parce que les notions abordées sont importantes).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre éclairé Avatar de MicaelFelix
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    254
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 254
    Par défaut
    Merci de ta réponse.

    En fait j'ai trouvé l'erreur, j'ai fait une ptite inattention au niveau de l'écriture de mon code, je rajoutais "&" devant le nom de la variable qui est un pointeur... alors je ne sais pas ce que ça faisait à l'interne mais je devais fournire l'adresse d'une adresse? Bref ça ne marchais pas...

    Quand tu me disais que mon memcpy n'allait pas fonctionner c'est surement à cause du & en trop?

    En fait côté programmation je n'ai pas le choix je dois forcément utiliser memcpy.
    Je travaille pour créer un protocole pour un simulateur (QualNet), les données sont fournies tout sous la forme de pointeurs (char *) et il faut que j'utilise le même système (memcpy) pour décoder l'information.

    Prochaine étape:
    Vu que je veux faire une copie totale de data, je suppose que je vais devoir réserver l'espace de l'objet à importer avec malloc et copier les données avec memcpy de la même manière, le tout en prenant en compte le dataSize déjà qui a déjà subi son typecast.

  4. #4
    Membre éclairé Avatar de MicaelFelix
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    254
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 254
    Par défaut
    Il me reste juste un problème à régler/comprendre et je pense que je serai bon pour me débrouiller tout seul pour une bonne partie de la suite. J'ai mis mon code pour donner plus d'indices:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef
    struct struct_app_detection_data_str
    {
    	char type;
    	size_t dataSize;
    	char *data;
    }
    DetectData;

    La génération du paquet de données (contenant une donnée dynamique) se fait ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    DetectData sentData;
    
    sentData.type = (char) MSG_DETECT_CFS_Request; //MSG_DETECT_CFS_Request=99
    
    // Valeur de test à envoyer
    int myValue = 6;
    sentData.dataSize = sizeof(myValue);
    //Allocation de la mémoire
    char *dataContainer = (char *)MEM_malloc(sentData.dataSize);
    //Stockage
    memcpy(dataContainer, &myValue, sentData.dataSize);
    
    sentData.data = dataContainer;

    La réception du paquet de données se fait ainsi:
    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
    DetectData *recData;
    recData = (DetectData *)MEM_malloc(sizeof(DetectData));
                
    memcpy(recData, MESSAGE_ReturnPacket(msg), sizeof(DetectData)); // MESSAGE_ReturnPacket(msg) renvoie le message précédemment créé sous forme de pointeur (char *)
    printf("recDetectData->type : %d\n",(int)recData->type);
    if(recData->data==NULL)
    	printf("recDetectData->data : NULL\n",(int)recData->type);
    printf("recDetectData->dataSize : %d\n",recData->dataSize);
    
    if(recData->dataSize>0)
    {
    	int myNewValue;
    	memcpy(recData->data, &myNewValue, recData->dataSize);
    	printf("recData->data : %i\n",myNewValue);
    }
    Tout est bon (dataSize, type, et le pointeur data n'est pas vide) sauf... myNewValue
    La valeur retournée par myNewValue semble varier donc je suppose qu'il y a un problème au niveau de la mémoire soit dans memcpy soit au niveau de l'allocation (ou bien c'est au niveau du transfert des données).

    Est-ce que les instructions mises en gras semblent être correctes selon vous?

    Merci d'avance.


    EDIT: cela pourrait être lié au fonctionnement du simulateur? j'ai l'impression que le pointeur *data se perd

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je pense qu'il faudra consulter la documentation des fonctions pour savoir précisément comment les données sont retournées. Seule la doc (ou le code des fonctions en question) peut indiquer qui a la responsabilité de l'allocation et de la désallocation du pointeur data.
    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.

Discussions similaires

  1. Réponses: 0
    Dernier message: 10/01/2013, 12h04
  2. Modifier la structure d'une table par macro / vba
    Par zermatt dans le forum Access
    Réponses: 8
    Dernier message: 21/01/2007, 15h32
  3. Réponses: 4
    Dernier message: 20/11/2006, 01h02
  4. [PHP-JS] structure de page appellee par include
    Par Pyrhus dans le forum Langage
    Réponses: 5
    Dernier message: 26/05/2006, 12h27
  5. Récuperer structure et contenu d'une base
    Par nero dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 24/06/2004, 17h34

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