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 :

Création de pointeur et allocation de mémoire


Sujet :

C

  1. #1
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut Création de pointeur et allocation de mémoire
    Bonjour voila ... Je me pose des questions sur ma declaration de pointeur et son allocation de mémoire ...

    Je vous transmet les info's ... Est ce que vous pourriez me dire si c'est correct ?

    Merci d'avance

    Ma structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct packetRec{
      char control;
      char lenght;
      unsigned short checksum;
      char *data;    
    };
    Ma declaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // Creation du pointeur
    struct packetRec *packet;
    // Allocation de la taille.
    packet = malloc(sizeof(struct packetRec));
    // Mise à zero.
    memset(packet, 0x0, sizeof(struct packetRec));

  2. #2
    Membre chevronné Avatar de cmoibal
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2007
    Messages : 361
    Par défaut
    Bonjour,
    est ce qu'il y a une erreur dans ce code ??

  3. #3
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Non, aucune erreur je pense ... Enfin il ne dit rien a la compilation ...

    Mais la question que je me pose, c'est que comme dans ma structure, j'ai une chaine de caractere non définie en taille ... Et que je ne fais qu'un malloc a la création du pointeur ... Et que je ne sais pas combien vaudra ma chaine de caractere dans ma structure ... Est ce que cela ne pourrait pas poser probleme ? :s

  4. #4
    Membre chevronné Avatar de cmoibal
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2007
    Messages : 361
    Par défaut
    oui, un pointeur sur une zone non reservé posera un problème...

    le malloc de la structure : c'est une allocation de la memoire pour le pointeur de la structure seulement.


    et pour le pointeur de la chaine de caractere il faut faire une nouvelle malloc.

  5. #5
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Le probleme, c'est que je ne connais pas la taille de la chaine de caractere ... Elle est variable ...

    Enfaite je t'explique tout ...

    Je recois des packet que l'on ma envoyé sur le réseaux ... Ce paquet est mis dans un buffer ...

    Je créée mon pointeur vers la structure ... Mais le probleme c'est que dans le packet que je recois, j'ai plusieur parametre ... 3parametres de taille connu .. Puisque declaré dans un format d'une taille connu ... Mais la chaine de caractere correspond au reste des donnée du packet recu ... Et donc je ne sais pas definir ca taille ... Et donc j'ai du mal a faire un malloc

    Je te place mon code entier peut etre pour que tu puisses mieux visualiser la situation ...

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    // ********************************************************
    // Fonction Receive
    // ********************************************************
    void receive(statMeasRead *cluster1, commParaReadWrit *cluster2, packetRejected *cluster3){
     
     
      int sel;
      fd_set read;
      struct timeval timeout;
      unsigned short saveChecksum;
      unsigned short returnChecksum;
     
      timeout.tv_sec = 0;
      timeout.tv_usec = 100000;
     
      FD_ZERO(&read);
      FD_SET(idSocket, &read);
     
      sel = select(idSocket + 1, &read, NULL, NULL, &timeout);
     
      // Probleme avec la fonction select.
      if(sel == SOCKET_ERROR){
        sprintf(codeErreur,"%d",WSAGetLastError());
        MessageBox(NULL,codeErreur, "Erreur receive : fonction select() !",MB_OK|MB_ICONERROR);
      }
     
      // Temps écoulé pour la fonction select.
      else if(sel == 0){
        MessageBox(NULL,codeErreur, "Erreur receive : select() timeout!",MB_OK|MB_ICONERROR);
        step = 3;
      }
     
      // Il y a un message a recuperer.
      else{
     
        //S'il y a une action a faire pour recv ... la fonction est faite
        if(FD_ISSET(idSocket, &read)){     
          nbCaractere = recv(idSocket, recbuf, 15-1, 0);
     
          // Erreur lors de la fonction rec().
          if(nbCaractere==SOCKET_ERROR){
    	    sprintf(codeErreur,"%d",WSAGetLastError());
    	    MessageBox(NULL,codeErreur, "Erreur receive : fonction recv() !",MB_OK|MB_ICONERROR);
     
    	    //Le serveur est mort, code erreur = 10054.
    	    if(strcmp(codeErreur,"10054") == 0) step = 3;
          }    
          else{
    	    recbuf[nbCaractere]='\0'; // Permet de fermer le tableau après le contenu des data, car la fonction recv ne le fait pas
     
    	    // Creation du pointeur
    	    struct packetRec *packet;
     
    	    // Allocation de la taille.
    	    packet = malloc(sizeof(struct packetRec));
     
    	    // Mise à zero.
    	    memset(packet, 0x0, sizeof(struct packetRec));
     
    	    memcpy((void*)packet, (const void*)recbuf, nbCaractere);
     
    	    // Test du checksum.
    	    saveChecksum = packet->checksum;
    	    packet->checksum = 0;
    	    returnChecksum = checksum((unsigned short *)packet, packet->lenght);
     
    	    if(saveChecksum == returnChecksum) packet->checksum = saveChecksum;
     
    	    // Test du byte de control si checksum OK
    	    if(packet->checksum != 0){	
     
    	      // Status and Measures reading (PLC answer)
    	      if(packet->control == 0x02){	        
    	        memcpy((void *)cluster1, (const void*)recbuf, nbCaractere); 
              }
     
    	      // Command/Parameter reading or writing (PLC answer)
    	      if(packet->control == 0x12 || packet->control == 0x17){       
    	        memcpy((void*)cluster2, (const void*)recbuf, nbCaractere);
              }
     
    	      // PLC answer at a "parameter/command writing" request by "Last packet rejected"
    	      if(packet->control == 0x18){	        
                memcpy((void *)cluster3, (const void*)recbuf, nbCaractere);
              }
            }
    	    else MessageBox(NULL,"Le calcule du checkSum à trouvé une erreur", "Erreur receive : fonction checksum() !",MB_OK|MB_ICONERROR);
     
    	    //Liberation de la mémoire.
            free(packet);
            packet = NULL;                       
          }
        }
      }
    }

  6. #6
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    C'est dangereux ton truc, parceque ta structure paquet ne représentera pas le paquet réel. En effet l'espace que tu alloueras dynamiquement pour la chaine ne sera pas à la suite du checksum !

    De plus comment tu peux lire une trame si tu ne connais pas sa longeur ?

    Je te propose (en gros) :

    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
     
    struct packetRec
    {
      char control;
      char lenght;
      unsigned short checksum;
      char data[];    
    };
     
    unsigned char recbuf[beaucoup];
     
    read(recbuf, 4);
    length = ((packetRec *)recbuf)->length;
    read(recbuf + 4 , length);
     
    /* et puis là soit tu travaille sur le recbuf, soit tu travaille sur une nouvelle trame allouée */

  7. #7
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Je connais ca taille maximum ... Mais ca peut varier entre 4valeurs ...

    La fonction read lit les messages sur le réseaux ?

    En suivant ton principe ... Comme je sais que la taille du paquet est dans la deuxieme cellule de mon recbuf ... Ne puis je pas faire quelque chose dans le gout de

    packet->data = malloc(((recbuf[1])-6) * sizeof(char));

    6 correspond au valeur de taille connue ...
    le control, la taille, le checksum et l'id (que j'ai oublié de definir dans ma structure) qui correspond a une taille de 6(*8) ...

  8. #8
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Citation Envoyé par nuFox Voir le message
    Je connais ca taille maximum ... Mais c apeut varier entre 4valeurs
    Personnellement, j'allouerais la taille maximale pour stocker l'ensemble de la chaine de caractères.

    Sinon, en principe, elle devrait logiquement se terminer par le caractère '\0', tu peux toujours mersurer la taille et allouer selon la valeur correspondante.

  9. #9
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Xcuse moi homeostasie
    J'ai édité mon message et je n'ai pas vu ta réponse avant

  10. #10
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Citation Envoyé par valefor
    C'est dangereux ton truc, parceque ta structure paquet ne représentera pas le paquet réel. En effet l'espace que tu alloueras dynamiquement pour la chaine ne sera pas à la suite du checksum !
    Je suis d'accord!

    Après le PO a t'il la possiblilité de modifier le format des trames circulant sur le réseau, notamment un champ pour le nombre de carctères à recevoir?

  11. #11
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Citation Envoyé par homeostasie Voir le message
    Je suis d'accord!

    Après le PO a t'il la possiblilité de modifier le format des trames circulant sur le réseau, notamment un champ pour le nombre de carctères à recevoir?
    Xcuse moi, Je ne comprend pas ce que tu veux dire ...

    Le paquet que je recois correspond a un paquet que m'envoie un automate ... Le but étant de traiter les informations contenue dans ce paquet ... Et donc non il n'y a pas de modification du paquet !

  12. #12
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    Bon admettons que tu fasses comme tu dis. Ça va marcher.

    Mais je ne sais pas ce que tu va faire ensuite de ton pointeur "paquet". Imaginons que tu veuilles :
    - le copier : problème : tu devras aussi copier paquet->data
    - le supprimer : problème : tu devras penser à libérer paquet->data

    Donc :
    - Soit tu travaille à la volée directement sur recbuf.
    - Soit tu crées des instances de tes paquets dont la taille fera exactement leur longueur. Ceci est réalisé en récupérant l'intégralité (quoi que ...) du paquet dans recbuf, puis en allouant un paquet de la bonne taille et d'un seul bloc, puis en copiant recbuf dans l'espace alloué.

  13. #13
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Citation Envoyé par nuFox Voir le message
    Xcuse moi, Je ne comprend pas ce que tu veux dire ...

    Le paquet que je recois correspond a un paquet que m'envoie un automate ... Le but étant de traiter les informations contenue dans ce paquet ... Et donc non il n'y a pas de modification du paquet !
    Je voulais savoir si c'était toi qui avait défini le format des trames circulant sur le réseau, c'est à dire la trame qu'envoie l'automate. Apparemment non.

    Sinon, je vois que tu dis:
    Citation Envoyé par nuFox
    Mais le probleme c'est que dans le packet que je recois, j'ai plusieur parametre ... 3parametres de taille connu .. Puisque declaré dans un format d'une taille connu ... Mais la chaine de caractere correspond au reste des donnée du packet recu ... Et donc je ne sais pas definir ca taille ... Et donc j'ai du mal a faire un malloc
    Suite à ton appel de fonction recv(), tu récupères le nombre d'octets reçus. Puisque que tu connais la taille de tes autres champs excepté le dernier, correspondant à la chaine de caractères, je pense que tu peux déduire la taille de celui-ci.

  14. #14
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Je n'utilise le packet seulement pour pouvoir recuperer la valeur de checksum facilement et aussi la valeur de controle ...

    Le reste je m'en fou ... c'est une sorte de cluster tampon ... Comme tu as pu le voir dans mon code ... Je le supprime directement après les operations finie ... Et quand je copie dans ma structure interne a un autre programme je n'utilise meme pas le pointeur, mais bien le recbuf ...

    Comme tu peux le voir dans le code ...

  15. #15
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Citation Envoyé par homeostasie Voir le message
    Je voulais savoir si c'était toi qui avait défini le format des trames circulant sur le réseau, c'est à dire la trame qu'envoie l'automate. Apparemment non.
    Le format a été défini ... Tout les packets ont été pensé sur papier, pour que tout le monde travaille avec les meme paquet.

    Citation Envoyé par homeostasie Voir le message
    Suite à ton appel de fonction recv(), tu récupères le nombre d'octets reçus. Puisque que tu connais la taille de tes autres champs excepté le dernier, correspondant à la chaine de caractères, je pense que tu peux déduire la taille de celui-ci.
    Je pense aussi, c'est de la que vient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    packet->data = malloc(((recbuf[1])-6) * sizeof(char));

  16. #16
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Citation Envoyé par nuFox
    Je pense aussi, c'est de la que vient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    packet->data = malloc(((recbuf[1])-6) * sizeof(char));
    Ok, je n'avais pas fait attention.

    Sinon, juste comme cela, sizeof(char) sera toujours égale à 1.

  17. #17
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Lol ...

    Je vais l'enlever alors

  18. #18
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Ca a l'air de fonctionner en tout ca ...

    Quand je libere un pointeur ... Dans mon cas, je dois bien faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    free(packet->data);
    packet->data = NULL;
    free(packet);
    packet = NULL;
    Et est ce que c'est mieux de mettre un buffer a blanc ... Avant de le réutiliser ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    memset(recbuf, 0x0, sizeof(recbuf));

  19. #19
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    C'est tout bon pour la libération.

    Pour le remplissage de zéros, je dirais que c'est facultatif.

  20. #20
    Membre éclairé
    Inscrit en
    Février 2008
    Messages
    302
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 302
    Par défaut
    Merci de vos réponses et de votre patience

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/03/2012, 06h56
  2. Pointeur, structure, allocation mémoire
    Par rirola12 dans le forum C
    Réponses: 4
    Dernier message: 22/04/2010, 17h14
  3. Réponses: 6
    Dernier message: 07/07/2007, 18h12
  4. Réponses: 6
    Dernier message: 24/03/2006, 18h24
  5. pb d'allocation de mémoire
    Par shura dans le forum C
    Réponses: 7
    Dernier message: 17/04/2005, 21h10

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