Prenons en exemple ce main:
|
|
Output :
/tmp » ./a.out
Adress alloc (before incrementation) = 0x55f8c66ed260
Adress alloc (after incrementation) = 0x55f8c66ed261
Value of alloc[0] = b
Value og alloc[-1] = a
J’ai alloué 100 octets avec malloc.
À l’offset 0 j’ai assigner la valeur ‘a’ puis j’ai incrémenté mon pointeur de 1, et j’ai assigné la valeur ‘b’.
Pour incrémenter notre pointeur, nous avons juste a l’incrémenter comme si nous incrémentons un index.
À la ligne 13, alloc pointe sur l’adresse : 0x55f8c66ed260
J’assigne la valeur ‘a’ a cette adresse. (ligne 13)
J’incrémente ensuite alloc de 1(ligne 17).
Alloc pointe maintenant 1 octets plus loin : 0x55f8c66ed261
J’assigne la valeur ‘b’ a l’offset 0 (qui est en réalité l’offset 1 devenue l’offset 0 du a notre incrémentation)
On voit clairement que le pointeur a été incrémente de sizeof(char) * 1 octets.
Rien de spécial, j’ai incrémenté mon pointeur de 1 octets, normal que je suis 1 octet plus loin.
Voyons maintenant le pourquoi de cet article.
Que ce passe t’il si je fais la même chose avec un type multi octets (uint64_t, uint32_t, struct, …)?
|
|
Dans ce code, on a une structure qui fait combien d’octet a votre avis ?
Je vais faire un article sur le padding pour ceux qui ont répondu 25.
La bonne réponse est 32.
Donc on a une structure de 32 octets, une allocation de la taille de notre struct * 100.
Une assignation de deux éléments de notre structure, une incrémentation et une autre assignation.
Output de ce main :
/tmp » ./a.out segfault42@segfault42-pc
sizeof t_struct = 32
address alloc = 0x55f4a3e46260
alloc->var_a = 1
alloc->var_b = 2
address alloc = 0x55f4a3e46280
alloc->var_a = 3
alloc->var_b = 4
address alloc = 0x55f4a3e46260
alloc->var_a = 1
alloc->var_b = 2
À votre avis, après le alloc++ mon pointeur sera incrémenté de combien d’octet ?
On voit ici qu’en incrémentent de 1 (alloc++), notre pointeur ne s’incrémente pas de 1 octet, mais de sizeof(son type).
Je passe de l’adresse 0x55f4a3e46260 a 0x55f4a3e46280.
J’ai bien les bonnes valeurs dans mes deux variables quand j’affiche leur contenue avec la fonction print_value.
Si je décrémente, je me retrouve bien a -sizeof(mon type) et le contenue de mes 2 variables et toujours le même.
Donc pour résumer, contrairement à ce qu’on pourrait penser, quand on incrémente un pointeur, en faisant notre_variable++ ou notre_variable += 1 ou même notre_variable = notre_variable + 1, on n’incrémente pas de 1 octet, mais de sizeof(le type de notre variable).
Une incrémentation de pointeur revient à faire notre_variable += sizeof(notre_variable) + 1.