Comme le dit Bayard, un pointeur est un panneau indicateur (vers un bloc de mémoire), il ne contient rien en lui-même. Il est donc inutilisable tant qu’il n’est pas initialisé avec une adresse mémoire valide (comprendre, qui a été allouée d’une façon ou d’une autre par/pour le programme).
Assigner une valeur quelconque à un pointeur non-initialisé (comme le fait ton code) revient à essayer d’écrire à un emplacement aléatoire de la mémoire –*c’est l’erreur de segmentation assurée*!
Il te faut donc d’abord initialiser ton pointeur, avant de le déréférencer, soit en lui assignant l’adresse d’une autre variable*:
…soit en lui allouant de façon dynamique la mémoire nécessaire au type du pointeur*:
int *pi = malloc(sizeof(int));
(Ne pas oublier, dans ce dernier cas, de libérer cette mémoire une fois qu’on en a plus besoin,
free(pi)…).
Une bonne pratique consiste à toujours assigner la valeur
NULL (l’adresse mémoire 0) à un pointeur qui n’est pas valide, cela permet de tester très simplement s’il l’est ou pas*:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| int main() {
int *pi = NULL;
int i = 1;
if (pi)
printf("Valid int pointer (value: %d): %p\n", *pi, pi);
else
printf("NULL int pointer!\n");
pi = &i;
if (pi)
printf("Valid int pointer (value: %d): %p\n", *pi, pi);
else
printf("NULL int pointer!\n");
pi = malloc(sizeof(int));
/* Attention, malloc n'initialise pas la mémoire allouée, sa valeur est donc aléatoire! */
if (pi)
printf("Valid int pointer (value: %d): %p\n", *pi, pi);
else
printf("NULL int pointer!\n");
/* Et on n'oublie pas de libérer la mémoire! */
/* XXX Attention à ne pas faire ça si pi pointe sur une variable, c-à-d si la mémoire concernée na pas été allouée dynamiquement sur le tas (heap)! */
if (pi)
free(pi);
return 0;
} |
Sinon, pour répondre à ta question (qui revient en gros à «*pourquoi préférer la syntaxe “variable” à la syntaxe “pointeur” quand c’est possible*»), et bien la réponse est simple*: parce que c’est plus simple*! Au lieu d’avoir à gérer deux informations dans le code (l’adresse et la valeur), on n’en a qu’une à gérer (la valeur), donc moins de gymnastique genre
(*pi)++ (ou pire encore,
*(pi++),
side effects included!), donc code plus facile à lire, et moins de risques d’erreur*! Et puis c’est bien connu, la première qualité du programmeur est d’être paresseux*!
Partager