Utilisation de Memcpy et type de données

Résolu
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008 - 6 mars 2008 à 12:40
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008 - 7 mars 2008 à 12:05
Bonjour,

Un petit probleme (surement simple, étant nioub) a vous soumettre :

Je dispose d'une structure de ce type :

typedef unsigned short int   uint16;
typedef unsigned long int    uint32;

typedef struct
{
   uint32   d1;
   uint16   d2;
   uint32   d3;
} data;

Je reçois dans un tableau "tab" 10 octets. Donc de la meme taille que ma structure.

Lorsque je fais un memcpy(&data, &tab[0], 10); je m'attends a remplir ma structure avec les valeurs du tableau. Mais voila, ca ne marche pas du tout.En fait, lorsque je demande l'affichage des adresses mémoire de d1, d2 et d3, je m'appercois que je vais toujours de 4 octets en 4 octets.
Ex : 0x80000000, 0x80000004, 0x80000008.

Or, vu que d2 a une taille de 2 octets, je pensais obtenir plutot :
Ex : 0x80000000, 0x80000004, 0x80000006.

Evidemment, comme cela ne fonctionne pas, la valeur de data.d1 est correcte, mais après data.d2 et data.d3 sont fausses...

Le pire, c'est qu'en changeant d1 en type long, je passe bien a 8 octets:
Ex : 0x80000000, 0x80000008, 0x8000000b.

Au secours.
A voir également:

7 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
6 mars 2008 à 14:05
Bonjour,


Tu peux gérer la valeur de l'alignement.

Ca risque de dépendre du compilo, mais pour VC, il y a pragma pack.

Tu peux l'utiliser comme ça :
#include <stdio.h>
#include <stdlib.h>

typedef unsigned short int uint16;
typedef unsigned long int uint32;

typedef struct
{
uint32 d1;
uint16 d2;
uint32 d3;
} data;

#pragma pack(1)
typedef struct
{
uint32 d1;
uint16 d2;
uint32 d3;
} datap;
#pragma pack()

int main()
{
printf("Alignement par defaut : %d\n", sizeof(data));
printf("Alignement sur un octet : %d\n", sizeof(datap));
system("pause");
}


Ce genre de truc est a faire seulement si on est obligé, car cela peut fortement affecter les performances.
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
6 mars 2008 à 12:50
Normal tout ceci comme expliqué déjà plusieurs fois sur ce forum.

Ta struct est bancale, les données sont mal alignées alors ton compilo les a correctement alignées sur 4.

Ta struct est donc en réalité:
typedef struct
{
  uint32   d1;
  uint16   d2;
  uint16   dummy;
  uint32   d3;
} data;

Il faut écrire:
typedef struct
{
  uint32   d1;
  uint32   d3;
  uint16   d2;
} data;
si tu ne veux pas que le compilo y retouche.

ciao...
BruNews, MVP VC++
0
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008
6 mars 2008 à 13:32
Complément d'info :
Je recois des valeurs dans un buffer (tableau). Ces données proviennent d'un GPS et envoie des trames au format Garmin. Les données sont envoyées "en série" de longueur variable, et placée dans une structure (nommé PVT data par Garmin) qui mélange les données de 16, 32 et 64 bits dans un ordre bien particulier.
 Donc a part faire un découpage de chaque valeur, il n'y a pas d'autres solutions ? Dans la trame Garmin, il n'y a pas de donnée "dummy". Meme si le découpage donnée par donnée peut fonctionner, je trouvais cela un peu "bricolage".

Enfin merci tout de même pour l'explication !!!
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
6 mars 2008 à 14:19
Clair que si le format ne dépend pas de soi, il ne reste que pragma pack.

Attention que dans les données GPS, il y a du BigEndian mixé avec du LittleEndian dans les structures, c'est le souk.

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008
7 mars 2008 à 10:57
Je vais essayer tout cela. Cela dit je suis sous Ubuntu / GCC 4.2 / Code::Blocks. Donc je ne pense pas que cette directive s'applique. Mais au pire il y a surement un équivalent. je vais chercher un peu et je repost dès que j'ai la solution.

A+
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
7 mars 2008 à 11:09
Je viens de tester sous gcc/Code::Blocks/XP.
Aucun problème.
0
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008
7 mars 2008 à 12:05
#pragma pack a résolu mon probleme...

Je dispose enfin des bonnes valeurs de mon antenne GPS !!!

Merci a vous deux !
0
Rejoignez-nous