Courir à travers une structure et d'imprimer toutes les valeurs?
J'ai un pointeur vers une structure et je voudrais récupérer l'ensemble de ses membres par essai et erreur. Je suis en train de courir à travers la structure par incrémentation du pointeur par un et derefencing il. Elle doit retourner une valeur correcte de la structure (tous les i*sizeof(int)
moment), mais il ne le fait pas.
Ce que je fais mal?
fn (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
{
/*
assume that all struct members are int types
typedef struct
{
mach_msg_bits_t msgh_bits;
mach_msg_size_t msgh_size;
mach_port_t msgh_remote_port;
mach_port_t msgh_local_port;
mach_msg_size_t msgh_reserved;
mach_msg_id_t msgh_id;
} mach_msg_header_t;
size of the struct is 24.
*/
printf("ID: %d \n",InHeadP->msgh_id); //prints 'ID: 1337'
printf("Ptr: %p\n",InHeadP);
for (int i = 0; i <= 24; i++)
{
int deref = *((int*)(InHeadP+i));
printf("InHeadP[%d]=%d\n",i,deref);
//no sign of 1337 anywhere
}
}
P. S. je sais que je ne devrais pas faire ça, mais c'est uniquement pour des fins de test.
int *deref
? N'avez-vous pas direint deref
?- Oui.
int deref = *((int*)(InHeadP+i))
. Changé. - "Il doit retourner une valeur correcte de la structure (chaque i*sizeof(int) temps) mais il ne fonctionne pas." -- Heu pourquoi devrait-il? ce n'est pas exactement la façon dont la mémoire est attribué.
- Êtes-vous sûr que tous ces domaines sont en 32 bits? Si msgh_id est de 16 bits, vous ne verrez jamais un
int
c'est-à 1337. (Viens de voir votre assumer tous les types struct... commentaire. Encore, cela pourrait en fait être le cas?) - est-ce votre machine mot de 4 octets de long? en outre, ce qui ne sizeof (mach_msg_header_t) retour?
mach_msg_id_t
est deint
type. Pas sûr de la taille de celui-ci.- Taille de
mach_msg_header_t
est de 24.
Vous devez vous connecter pour publier un commentaire.
Parce que
InHeadP
est unmach_msg_header_t*
, l'ajout d'un nombre entier, il sera effectivement ajouter ce nombre entier de foissizeof(mach_msg_header_t)
, comme si vous étiez l'indexation d'un tableau demach_msg_header_t
s (et est en fait la façon dont la matrice de l'indexation des œuvres). Vous avez besoin de jeterInHeadP
à unint*
avant exécution de l'arithmétique, et même alors, la structure a six champs,i
ne doit aller jusqu'à 6, pas 24.*(((int*)(InHeadP))+i)
travaillé! Merci!Une méthode préférée pour itérer à travers une structure est de créer une fonction qui retourne la valeur ou de l'adresse du champ donné un indice. Notez que si l'ordre des membres de la struct changements, cette fonction doit changer:
Suffit de se rappeler que le traitement de la structure comme contiguë champs (membres) n'est pas conseillé, car le compilateur est autorisé à ajouter du rembourrage entre les membres de structure. Ainsi, une méthode pour accéder à la champs à l'exception de par son nom, est dangereux et va entraîner très difficile de bugs.
BTW, le traitement de chaque champ comme un
int
est également dangereux. Si l'un des types est changé en quelque chose d'autre, comme undouble
, votre code de casser. Le compilateur va pas de capture de l'erreur à cause de la coulée indique au compilateur que VOUS savez ce que vous faites.Vous pourrait "tourner l'image autour de" et de mettre en œuvre un Visiteur modèle:
Non, vous ne devriez pas faire ça!
Ce qui est particulièrement mal ici
est que l'impression de la première int de 24 différentes structures.
Lorsque vous appelez (int*)(InHeadP+i) vous faites de l'arithmétique des pointeurs sur mach_msg_header_t qui est de la taille 24. Donc, votre première itération est au début de la structure, et votre deuxième itération est juste après votre structure. Vous accédez à certains autres de la mémoire.
Essayer (((int*)InHeadP)+i).
Attendez une seconde, ce qui est faux:
Vous voulez
Vous sauter 24 octets à chaque fois dans la boucle, plutôt que 4.