C pointeur math avec des structures

En essayant de mieux apprendre les mathématiques de pointeur, j’ai écrit ce code. L’intention était d’incrémenter le pointeur a jeté la structure et imprimer ses membres. Je sais comment imprimer les noms des membres plus facilement, mais j’aimerais vraiment savoir comment mon calcul de pointeur est perturbé. Je vous remercie.

typedef struct{ int num; int num2; char *ssortingng; } astruct ; int main (int argc, const char * argv[]) { astruct mystruct = { 1234, 4567,"aaaaaaa"}; astruct *address; address = &mystruct; // this does print 1234 printf("address 0x%x has value of:%i\n",address, *address); address = address + sizeof(int); //this does NOT print 4567 printf("address 0x%x has value of:%i\n",address, *address); address = address + sizeof(int); //this crashes the program, I wanted to print aaaaaaaa printf("address 0x%x has value of:%s\n",address, **address); return 0; } 

L’arithmétique de pointeur incrémente un pointeur du nombre d’octets pointés. Par exemple,

 int a[2]; int *p = a; assert( &a[0] == p ) assert( &a[1] == p + 1 ) 

Par conséquent, votre ligne

 address = address + sizeof(int); 

change réellement d’ address en address + sizeof(int) * sizeof(astruct) (en utilisant l’arithmétique normale, pas celle du pointeur).

Il n’y a pas de moyen garanti de faire ce que vous essayez, car le compilateur est autorisé à introduire un remplissage dans une structure. Considérez la structure

 struct A { char a; int b; }; 

Le compilateur donnera probablement à cette structure la disposition suivante:

 +------------+-------------------+-------------+ | a (1 byte) | (3 bytes padding) | b (4 bytes) | +------------+-------------------+-------------+ 

Donc, vous ne pouvez pas arriver à b en prenant l’adresse d’une instance de struct et en ajoutant 1.

Dans votre cas spécifique , le compilateur n’introduit probablement pas de remplissage, vous pouvez donc utiliser ces lignes pour mettre à jour l’ address :

 address = (char *) address + sizeof(int); // OR... address = (int *) address + 1; 

Encore une fois, cependant, cela dépend entièrement de la manière dont le compilateur a structuré la structure, et toute modification mineure la cassera probablement. Vous ne devriez donc pas vous fier à ce type de comportement.

Lorsque vous ajoutez un pointeur, vous ajoutez en fait n * sizeof(*ptr) octets.

Par conséquent, sur une machine 32 bits où votre structure prendrait 12 octets, l’ajout de sizeof(int) octets appendait en réalité 48 octets au pointeur.

Pour pointer en num2 vous devez d’abord num2 adresse en un pointeur sur un entier:

 int *iaddress = (int *)address; 

puis ajoutez-en un pour atteindre votre valeur de 4567.

Les structures sont conçues pour éviter de tels types de calcul. Au lieu de parcourir la mémoire, vous pouvez utiliser mystruct.num , mystruct.num2 et mystruct.ssortingng . Et ce sera quand même une erreur de segmentation puisque vous n’allouez pas de mémoire pour ‘aaaaaaa’.