2017-05-28 1 views
-3
int main(){ 
    char * ptr = (char *) 0x1000; 
    *(char *)ptr = 0; //Illegal memory access 
    printf("ptr %p\n", ptr); //prints the address (hex); ptr is pointing memory location 0x1000. 
    printf("ptr %d\n", *ptr); //illegal memory access 
return 0;} 

l'extrait de code ci-dessus s'exécute sur ma machine Linux mais; Lorsque dans mon conseil cible 32bit ptr est pointeur volatile de type uint32 adresse de registre cartographié alors son OK pour écrire sur ce registre comme ci-dessous:Quel est le problème avec la logique ci-dessous c?

*(volatile uint32*)ptr = 0x00000001; 
+0

Quelle CPU/plateforme/système ciblez-vous? Quelle est la signification de l'adresse '0x1000' sur ce processeur/plate-forme/système? S'il s'agit d'un registre de 32 bits, vous ne pouvez pas lui écrire partiellement? –

+1

Est-ce que le changement à volatile est la modification ou le changement à uint32 *? – Yunnosch

+0

Les deux extraits de code ne sont pas liés les uns aux autres. Ma requête est liée à la manière d'affecter une valeur à une adresse. Quand je fais '* (volatile uint32 *) ptr = 0x00000001;' cela fonctionne très bien pour moi ici ptr pointe vers l'adresse cartographiée IO. Alors que lorsque je cours le premier petit fragment de code sur ma machine Linux, cela me donne une erreur de segmentation. –

Répondre

-2

Je ne sais pas ce que vous essayez de faire, mais je suppose que vous écrivez une sorte de firmware pour un microcontrôleur ou quelque chose de similaire. Votre question ressemble un peu plus au problème XY. C, étant un langage de programmation de bas niveau, dépend beaucoup plus des détails matériels qu'un langage de niveau supérieur tel que Ruby. Beaucoup dépendra du processeur et du système d'exploitation sous lequel ce code est exécuté. Essentiellement, vous posez des questions sur le comportement d'exécution d'un code, mais vous ne donnez pas assez d'informations sur l'endroit où ce code est exécuté.

Affecter des valeurs à des pointeurs directement ou non, n'importe où, cela dépend du processeur et du système d'exploitation. De même, tous les processeurs et ensembles d'instructions ne mappent pas les registres dans l'espace mémoire. Ainsi,

char * ptr = (char *) 0x1000;

OU

(uint32 volatile *) ptr = 0x00000001;

peut pointer vers un registre 32 bits ou peut pointer vers une mémoire physique ou peut pointer vers une adresse virtuelle valide ou peut pointer vers une adresse virtuelle invalide ou non mappée ou simplement pointer vers nulle part. Tout dépend du contexte matériel.

+1

Si vous avez des doutes sur les détails de la question OP, utilisez les commentaires pour clarifier. Si vous n'avez pas les privilèges pour le faire, alors cherchez une question qui vous est claire. Votre réponse semble hors de la question, qui est très précisément sur la raison pour laquelle la différence entre les deux méthodes peut faire un travail et l'autre pas. – Yunnosch

+0

@Yunnosch Avec les informations actuelles, ma réponse, à mon humble avis est en forme car elle explique ce qui ne va pas avec la logique «C», c'est l'hypothèse que C a un comportement cohérent quel que soit le matériel. Une fois qu'ils auront mis à jour leur question avec plus d'informations, je mettrai à jour ma réponse. Je crois que j'ai répondu à leur question de base. «Quel est le problème avec cette logique C? –

+0

Cela ne répond pas à la question en effet. De l'information donnée, nous avons seulement ce que la norme spécifie et cela signifie UB. "Avec les informations actuelles ..." - c'est exactement le point pour lequel des questions obscures ne pourraient pas être résolues. Commentez pour demander les informations requises. Jusqu'à ce que vous ayez les représentants, vous devez attendre les autres. Si vous fournissez une réponse de toute façon, il est susceptible d'être marqué ou downvoted. De toute façon, oyu n'obtiendra pas les représentants plus rapidement. – Olaf