J'ai initialisé le pointeur avec une constante, et je savais que son adresse sera fournie au pointeur. Ainsi, lorsque j'ai essayé de tester si la constante peut être imprimée ou non, le programme s'est écrasé. Est-ce illégal?
#include <stdio.h>
int main()
{
int *i = (int *)1;
printf("The value that i pointer points to is %d\n", *i);
return 0;
}
3 Réponses :
(int *) 1; n'est pas un pointeur vers la valeur 1. mais plutôt le pointeur vers la cellule mémoire # 1. Ce que vous voulez probablement, c'est
#include <stdio.h>
int main()
{
int n=1;
int *i = &n;
printf("The value that i pointer points to is %d\n", *i);
return 0;
}
printf("The value of pointer i is %p\n", i);Vous essayez de déréférencer le pointeur
i, mais sa valeur (la valeur du pointeur) est une valeur que vous définissez vous-même. Pouvez-vous garantir qu'à l'adresse0x0001est un entier que vous possédez? Tout ce que vous pouvez faire avec un tel pointeur est d'imprimer sa valeur de pointeur (pas la valeur vers laquelle il pointe):printf("The value that i pointer points to is %d\n", *i);
Vous semblez penser que (int *) 1 produit l'adresse où la valeur 1 est stockée. Ce n'est pas le cas.
Lorsqu'un cast tel que (int *) est utilisé pour convertir un entier en pointeur, le résultat est généralement que la valeur est transformée en adresse. 1
Ainsi, int * i = (int *) 1; définit i pour qu'il pointe vers l'adresse 1. Ensuite, en essayant de print * i , votre programme s'est écrasé car 1 n'était pas une adresse mémoire valide. (Assez couramment, la première page de mémoire est maintenue non mappée afin que les utilisations incorrectes du pointeur nul se plantent et révèlent un problème plutôt que de permettre au programme de continuer à s'exécuter avec des données incorrectes.)
Pour définir i pour pointer vers un int avec la valeur 1, vous devez le définir sur l'adresse d'un objet int qui a la valeur 1. Une façon de faites ceci est:
int *i = & (int) { 1 };
Vous pouvez également créer un int sans nom avec la valeur 1 en utilisant un littéral composé:
int n = 1; int *i = &n;
Le (int) {1} crée un littéral composé avec la valeur 1, et le & prend son adresse, puis i est initialisé à cette adresse.
1 Selon le standard C, le résultat est défini par l'implémentation. Ainsi, un compilateur peut définir n'importe quel résultat qu'il souhaite. Cependant, chaque compilateur C que j'ai vu transforme la valeur entière en une adresse, d'une manière ou d'une autre. L'adresse résultante n'est pas nécessairement valide à utiliser pour accéder à un objet.
Vous n'imprimez pas la constante du pointeur, mais le contenu vers lequel il pointe. Votre pointeur pointe vers l'adresse constante
0x1, qui n'est pas une adresse valide, donc votre programme plante.Vous attendiez-vous à une sortie particulière?