2009-12-12 3 views
0

Je voudrais comprendre pourquoi je reçois une erreur de bus avec ce code.Erreur de bus C++ dans l'architecture SPARC

int main() 
{ 
int p=34; 
int *pp= (int *) ((char *)&p+1); 
cout<<*pp<<"\n"; 
return 0; 
} 
+1

En dehors du problème d'alignement, il s'agit d'un comportement indéfini. Vous lisez hors des limites. En conséquence, le programme pourrait exploser de manière beaucoup plus imaginative. – jalf

Répondre

10

Ce sera sans doute un problème d'alignement. Sur de nombreuses architectures, certains types doivent être correctement alignés, un exemple étant que les entiers de 4 octets doivent commencer à sur une limite de 4 octets.

Si vous accédez à des données non alignées, certaines architectures ne s'en soucieront pas, d'autres seront plus lentes, d'autres encore (comme dans ce cas) tomberont dans un tas de cris.

Lorsque vous créer l'entier p, il sera aligné correctement sur la pile à une adresse qui est un multiple correct. En déplaçant cette adresse vers le haut sur l'octet, et en décrivant cela comme un int, vous provoquerez le SIGBUS.

This link à Oracle montre les exigences d'alignement. En résumé:

  • Les entiers courts sont alignés sur des limites de 16 bits.
  • Les entiers int sont alignés sur des limites de 32 bits.
  • Les entiers longs sont alignés sur des limites de 64 bits pour les systèmes SPARC.
  • Les entiers longs longs sont alignés sur des limites de 64 bits.
+0

Merci cela a beaucoup aidé! Je comprends ce qu'ils veulent dire par adresse non-alignée maintenant. – PJT

1

à des adresses qui sont un multiple de 4.

De nombreux processeurs prennent en charge un accès non alignée des quantités de 16 bits doivent être conservés à 16 bits ou un alignement de 2 octets, et 32 ​​bits (4 octets), mais cela coûte des circuits supplémentaires dans la puce, et un temps d'exécution supplémentaire pour exécuter les cycles de bus de mémoire supplémentaires pour ramasser les octets impairs. C'est une philosophie de processeur RISC particulièrement courante qui exige plus de précautions de la part des compilateurs et des programmeurs pour disposer des données avec soin pour une vitesse accrue et un circuit plus simple est un compromis acceptable. Par ailleurs, il est peu probable qu'une adresse basse comme celle-là soit de toute façon valide dans la mémoire valide. Mais votre exemple illustre que l'exception d'alignement est prioritaire sur l'exception SEGFAULT.