SCÉNARIO 1
int *nums = {5, 2, 1, 4}; // <-- assign multiple values to a pointer variable
printf("%d\n", nums[0]); // segfault
Pourquoi est-ce une erreur de segmentation?
Vous avez déclaré nums
comme un pointeur vers int - c'est - nums
est censé contenir l'adresse d' un entier dans la mémoire.
Vous ensuite essayé d'initialiser nums
d'un tableau de plusieurs valeurs. Donc, sans creuser dans les détails, c'est sur le plan conceptuel incorrect - il n'est pas logique d'attribuer plusieurs valeurs à une variable qui est censé tenir sur une seule valeur. À cet égard, vous pouvez voir exactement le même effet si vous faites cela:
int nums = {5, 2, 1, 4}; // <-- assign multiple values to an int variable
printf("%d\n", nums); // also print 5
Dans les deux cas (attribuer plusieurs valeurs à un pointeur ou une variable int), ce qui se passe ensuite est que la variable d'obtenir la première valeur qui est - 5
, tout en restant valeurs sont ignorées. Ce code est conforme, mais vous pouvez obtenir des avertissements pour chaque valeur supplémentaire qui n'est pas censé être en mission:
warning: excess elements in scalar initializer
.
Pour le cas de l'attribution de plusieurs valeurs de pointeur de variable, le programme de segmentation lorsque vous accédez nums[0]
, ce qui signifie que vous sont deferencing tout ce qui est stocké à l'adresse 5 littéralement. Vous n'avez pas à allouer de la mémoire pour le pointeur nums
dans ce cas.
Il serais intéressant de noter qu'il n'y a pas d'erreur de segmentation pour le cas de l'attribution de plusieurs valeurs à la variable int (vous n'êtes pas référence à toute pointeur non valide ici).
SCÉNARIO 2
int nums[] = {5, 2, 1, 4};
Celui-ci n'est pas l'erreur, parce que vous êtes légalement de l'allocation d'un tableau de 4 entiers dans la pile.
SCÉNARIO 3
int *nums = {5, 2, 1, 4};
printf("%d\n", nums); // print 5
Celui-ci n'a pas d'erreur de segmentation comme prévu, en raison de l'impression de la valeur du pointeur lui-même - non PAS ce que c'est d'être déréférencé (qui n'est pas valide d'accès à la mémoire).
D'autres
C'est presque toujours vouée à l'erreur de segmentation quand vous le coder en dur la valeur d'un pointeur comme ça (parce que c'est le système d'exploitation de la tâche de déterminer ce processus peut accéder à ce que l'emplacement de la mémoire).
int *nums = 5; // <-- segfault
Ainsi, une règle de base est de toujours initialiser un pointeur vers l'adresse de certains alloué variable, tels que:
int a;
int *nums = &a;
ou,
int a[] = {5, 2, 1, 4};
int *nums = a;