Je suis un débutant en informatique. J'ai appris qu'un pointeur est un type de données composé, qui indique l'adresse d'une donnée ainsi que le type et la taille des données. La conversion de type d'un pointeur ne modifie que la taille de lecture mais l'adresse de début. Pour le confirmer, j'ai fait une expérience.

Voir le code ci-dessous. J'ai changé le type de pointeur de la variable «échantillon», mais je pense qu'il pointe toujours le premier octet de l'échantillon. Rien n'a changé mais la taille. Ensuite, je fais sauter le pointeur (type char) à gauche d'un octet (c'est-à-dire "p = p-1" dans le code). Après cela, je le reconvertis en un type court. Je pense que les données pointées sont 0x..24 (.. signifie des données devant 0x2456). Enfin, j'utilise l'opération de bit "<<" pour passer à 0x2400. Cependant, j'ai des nombres aléatoires à chaque fois que je l'exécute.

   #include<stdio.h>

   int main(void){
       short sample = 0x2456;

       char *p = (char*) &sample; 
       p = p-1;
       printf("%d\n",*((short*)p)<<8 );
       return 0;
   }
c
-3
XM Zg 19 mai 2020 à 08:02

3 réponses

Meilleure réponse

À partir de votre code, je suppose que vous voulez décaler 0x24 vers l'octet supérieur (en fait inférieur). Essayez p=p+1 et voyez si vous obtenez les résultats souhaités.

Au lieu de lire le pointeur comme court, si vous faites (int)*p << 8, vous obtenez 2400 à chaque fois.

Ou vous pouvez faire quelque chose de fou comme l'initialisation d'une variable après l'initialisation du pointeur afin que lorsque nous déplaçons le pointeur, il n'obtienne pas la poubelle mais une partie de la variable

#include<stdio.h>

   int main(void){
       short sample = 0x2456;

       char *p = (char*) &sample; 
       int zero = 0;
       p = p+1;
       printf("%x\n",*((short*)p) << 8 ); 
       return 0;
   }

Vous pouvez même imprimer 0x1224 (la moitié des deux) comme ceci

   #include<stdio.h>

   int main(void){
       short sample = 0x2456;

       char *p = (char*) &sample; 
       int zero = 0x12;
       p = p+1;
       printf("%x\n",*((short*)p);    //will print 1224
       return 0;
   }

Remarque: j'ai supposé que les deux variables se trouvaient dans un seul cadre de pile et que la mémoire supposée était peu endienne. Les résultats peuvent changer avec les compilateurs et les systèmes cibles.

0
Pranav appu 19 mai 2020 à 08:54

La plupart des systèmes d'exploitation fournissent des randomisation de la disposition de l'espace d'adressage (pour des raisons de cybersécurité), y compris pour pile d'appels de votre main fonction appelée depuis crt0.

Je ne sais pas pourquoi je ne peux pas obtenir une valeur fixe.

ASLR peut expliquer pourquoi l'exécution de votre programme plusieurs fois sur votre système d'exploitation produit une sortie différente. Votre p probablement pointe vers un emplacement étrange de la pile d'appels.

En savoir plus sur le comportement indéfini , et aussi Modern C puis la spécification de C11 , à savoir n1570.

Si vous utilisez un GCC récent pour compiler votre code C foo.c, envisagez de le compiler avec {{ X1}} puis regardez dans le code assembleur émis foo.s. Vous comprendrez alors quelle valeur est passée à printf. C'est spécifique à la mise en œuvre.

1
Basile Starynkevitch 19 mai 2020 à 07:55

Je vais juste prendre une photo dans le noir. Si vous souhaitez imprimer la valeur stockée dans les 8 premiers bits de l'échantillon (1 dans ce cas). Remarque, cela suppose que la mémoire est peu endienne:

short sample = 1;
char* p = (char*)&sample;
p = p - 1;
std::cout << "the first 8 bits of sample: " << (*(short*)p >> 8) << std::endl;
-1
John Colvin 19 mai 2020 à 15:35