2016-05-05 4 views
1

Lors de l'exécution de certains programmes, j'ai réalisé que les adresses virtuelles sont toujours des multiples de quatre (en supposant des adresses virtuelles 32 bits). Exemple:Adresses virtuelles: multiples de quatre alignés - écriture à adresser "entre"

int main() 
{ 
    int a = 7; 
    int b = 10; 
    printf("%p %p", &a, &b); 
} 

donnera quelque chose comme:

  • xff86c930 0xff86c934
  • xfff58f80 0xfff58f84
  • ...

La différence entre eux est toujours quatre. Maintenant, je essayé ceci:

sortie
int main() 
{ 
    int a = 7; 
    int b = 10; 
    int *y = &b; 
    int yi = (int)y; 
    yi--; 
    y = (int*)yi; 
    printf("%p %p: %d\n", &b, y, *y); 
    *y = 7; 
    printf("%p: %d\n", y, *y); 
} 

Un exemple est:

0xffe460a0 0xffe4609f: 2807

0xffe4609f: 7

Qu'est-ce qui se passe ici? Qu'est-ce qui est référencé lorsque j'essaie d'écrire quelque chose à une adresse qui n'est pas un multiple de quatre? D'où vient ce 2807? Y aura-t-il une faute de page?

+2

'les adresses virtuelles sont toujours des multiples de quatre' ce n'est pas vrai –

+0

Ceci est appelé Comportement non défini. Vous avez manipulé 'y' pour devenir un pointeur invalide. – kaylum

+0

@Lashane assumant cette architecture, c'est ... Je vais ajouter ceci à ma question. –

Répondre

1

Prenez y comme int (dangereux sur les systèmes 64 bits)

int yi = (int)y; 

Décrémenter son adresse comme un entier et non un pointeur - va l'amener à devenir non alignés.

yi--; 

Code dur que nouvel entier retour en tant que pointeur - ce pointeur est maintenant probablement très dangereux d'utiliser

y = (int*)yi; 

déréférencement le pointeur non aligné. Cela fera différentes choses sur différents systèmes en fonction du contrôleur de mémoire. Au mieux, il se faufile immédiatement afin que vous ne fassiez aucune supposition. Stomp un peu plus sur la mémoire non alignée pour le plaisir - pourquoi pas.

*y = 7; 

D'où vient le 2807? C'est ce que le contrôleur de mémoire veut vous donner. Peut-être que c'est la valeur de la poubelle plus tôt dans la pile, peut-être que c'est une valeur de baril décalée du mot ci-dessous, c'est complètement le choix du système.

Voici ce que @kaylum voulait dire avec son commentaire UB.

+0

Merci fort cela. –

+0

@Michael, pourquoi est-il nécessaire pour la mémoire d'être aligné avec 32 octets (sur processeur 32 bits), pourquoi il y a cette limite .... mon doute est que le processeur ne lit pas 32 bits à la fois, il lit une ligne de cache bloquer, alors pourquoi il y a alignement de 32 bits requis? cela devrait dépendre de l'alignement de la ligne de cache. –