51 votes

Mon char d'un pointeur sur une valeur non valide après avoir été chassé de int*

Je suis en train d'apprendre le langage C, j'ai juste commencé à apprendre des tableaux avec des pointeurs. J'ai un problème dans cette question, j'espère que la sortie doit être 5 , mais il est 2, quelqu'un Peut-il expliquer pourquoi?

int main(){
   int arr[] = {1, 2, 3, 4, 5};
   char *ptr = (char *) arr;
   printf("%d", *(ptr+4));
   return 0;
}

80voto

Andreas Points 16923

Supposé un little endian architecture où l'int de 32 bits (4 octets), les octets d' int arr[] ressembler à ceci (l'octet le moins important au plus faible de l'adresse. Toutes les valeurs en hexadécimal):

|01 00 00 00|02 00 00 00|03 00 00 00|04 00 00 00|05 00 00 00
char *ptr = (char *) arr;

Maintenant, ptr points pour le premier octet - puisque vous avez joué à l' char*, il est traité comme un tableau de char en avant:

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
 ^
 +-- ptr

Ensuite, *(ptr+4) accède à la cinquième élément de la char tableau et renvoie la correspondante char valeur:

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
         ^
         +-- *(ptr + 4) = 2

Par conséquent, printf() tirages 2.

Sur un Big Endian système, l'ordre des octets dans chaque int est inversé, ce qui

|0|0|0|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5
         ^
         +-- *(ptr + 4) = 0

13voto

Joachim Pileborg Points 121221

C'est parce que la taille de l' char est un, et la taille de l' int est de quatre. Cela signifie que l'ajout d' 4 de ptr le résultat au second point d'entrée dans l' int tableau.

Si vous avez compilé sur une big endian système que vous aurez édité 33554432 à la place.

3voto

md5 Points 14957
int main(){
 int arr[] = {1,2,3,4,5};
 char *ptr = (char *) arr;
 printf("%d",*(ptr+4));
 return 0;
}

Chaque cas d' arr a sizeof(int) taille (qui peut être de 4 sur votre mise en œuvre).

Depuis ptr est un pointeur vers char, l'arithmétique des pointeurs fait ptr + 4 points 4 octets après l' &arr[0], qui peuvent être &arr[1].

Dans la mémoire, il ressemble à quelque chose comme:

Address | 0 1 2 3 | 4 5 6 7 | ...
Value   |  arr[0] |  arr[1] | ...

2voto

Bathsheba Points 23209

Sur un 32 bits plate-forme, int , soit quatre fois la taille de l' char. Lorsque vous ajoutez 4 ptr, vous ajoutez 4 fois la taille de ce qu'ptr points de ptr (qui lui-même est un emplacement de mémoire). Qu'advient-il à l'adresse du deuxième élément de l' int tableau.

Sur une plateforme 64 bits, int est huit fois la taille de l' char; et votre résultat sera très différent.

Pour couper une longue histoire courte, votre code n'est pas portable, (voir aussi Joachim Pileborg la réponse de re endianness), mais de plus amusant que de plus.

2voto

ondav Points 341

Ce que vous faites est certainement pas recommandé dans le code de production, mais est certainement grande pour comprendre les pointeurs, les castes, etc. dans le processus d'apprentissage, pour cela, votre exemple est grande. Alors, pourquoi vous obtenez 2. C'est parce que votre tableau est un tableau d'entiers, qui, selon votre architecture a de taille différente (dans votre cas, sizeof(int) 4). Vous définissez ptr comme étant un pointeur de char, char a taille 1 octet. L'arithmétique de pointeur (c'est ce que vous faites quand vous écrivez ptr+4) travaille avec la taille des objets le pointeur de références, dans votre cas, avec les caractères. Ainsi, ptr+4 est de 4 octets à l'écart dès le début de votre tableau, et donc à la 2ème position de votre int tableau. Qui est-il. Essayez ptr+5, vous devriez obtenir 0.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X