Pointeur d'initialisation donne segmentation fault
J'ai écrit un programme en C, comme suit:
CAS 1
int *a; /* pointer variable declaration */
int b; /* actual variable declaration */
*a=11;
a=&b;/* store address of b in pointer variable*/
Il donne une erreur de segmentation lors de l'exécution du programme.
J'ai modifié le code comme suit:
CAS 2
int *a; /* pointer variable declaration */
int b; /* actual variable declaration */
a=&b;/* store address of b in pointer variable*/
*a=11;
Maintenant ça fonctionne.
Si quelqu'un sait s'il vous plaît expliquer pourquoi il donne une erreur de segmentation dans le CAS 1.
OriginalL'auteur EnterKEY | 2013-07-26
Vous devez vous connecter pour publier un commentaire.
Cela va être la faute de segmentation car l'adresse que vous utilisez n'est pas une adresse valide et là, vous êtes le stockage de 11, ce qui est illégal.
Maintenant sa fonctionne bien parce que l'adresse de b n'est valable un il vous stockez 11 qui est légal.
Aussi des cas ci-dessus ne sont pas de bonne façon de déclaration de pointeur
ou
Cela permettra d'éliminer faute de segmentation de nombreuses fois ce qui est difficile à trouver .
OriginalL'auteur pradipta
Dans le cas 1,
Il montre faute de segmentation en raison de l'affectation de valeur à une adresse mémoire qui n'est pas défini. Comportement indéfini.
Dans le cas 2,
Considérons cet exemple:
Ici c'est la façon dont il fonctionne.
Asuuming emplacement de mémoire de b est de 4000.
Après la manipulation, il ressemble à ceci.
OriginalL'auteur Amarnath Krishnan
Une seule ligne: Premier code que vous déréférencement du pointeur non initialisé, qui présente un comportement indéterminé, et dans le deuxième code, vous êtes un déréférencement du pointeur initialisé qui donnera accès à la valeur à l'adresse.
Un peu d'explication:
D'abord, vous devez réaliser qu'un pointeur n'est rien, mais un entier, un avec le
*var
nous dire au compilateur que nous serons en utilisant le contenu de la variablevar
(integer) comme une adresse pour récupérer la valeur de cette adresse. Si il y a**var
de même nous dire au compilateur que nous allons d'abord utiliser la valeur de la variablevar
pour aller chercher de la valeur à l'adresse et à nouveau utiliser cette extraites de la valeur que d'une adresse et d'aller chercher la valeur stockée.Donc dans votre première déclaration, c'est:
Puis vous essayez d'utiliser la valeur stockée dans
a
comme une adresse.a
contient des ordures, il peut être n'importe quelle valeur, mais vous n'avez pas accès à tout emplacement de l'adresse. Par conséquent, la prochaine fois vous ne*a
il va utiliser la valeur stockée dansa
comme une adresse. Parce que la valeur peut être n'importe quoi, tout peut arriver.Si vous avez la permission d'accéder à l'emplacement , le code continuera à s'exécuter sans erreur de segmentation. Si l'adresse se trouve être d'une adresse dans le segment de la comptabilité de la structure, ou une autre zone de mémoire où le code affecté à partir du segment ou de la pile, puis quand vous ne
*a = 10
il sera tout simplement essuyer la valeur existante avec10
à cet endroit. Cela peut conduire à un comportement indéterminé que maintenant vous avez changé quelque chose sans la connaissance du contexte ayant l'autorité de la mémoire. Si vous n'avez pas la permission de la mémoire, vous obtenez tout simplement une erreur de segmentation. Ceci est appelé le déréférencement d'un pointeur non initialisé.Prochain relevé de compte que vous ne
a = &b
qui attribue l'adresse deb
dansa
. Cela ne vous aide pas, parce que la ligne précédente a déréférencé un pointeur non initialisé.De code suivant vous avez quelque chose comme ceci après le troisième énoncé:
La troisième instruction assigne l'adresse de
b
ena
. Avant quea
n'est pas déréférencé, par conséquent, la valeur d'ordures stockées dansa
avant l'initialisation n'est jamais utilisé comme une adresse. Maintenant, lorsque vous affectez une adresse valide de vos connaissancesa
, déréférencementa
maintenant, vous donnera accès à la valeur pointée para
.L'extension de la réponse, vous avez besoin de garder un œil, même si vous avez attribué une adresse valide pour un pointeur, vous devez vous assurer au moment de déréférencement du pointeur de la durée de vie de l'adresse pointée par le pointeur n'a pas expiré. Par exemple le retour de variable locale.
Même dans le cas de l'accès à la mémoire libérée de l'emplacement du tas.
OriginalL'auteur phoxis
Dans le premier cas, vous avez déclaré un pointeur, mais vous n'avez pas affecté de l'adresse à laquelle il a à un point où le pointeur de la contenait une adresse qui aurait appartenu à un autre processus dans le système (ou il aurait contenu une valeur indésirable qui n'est pas une adresse ou il contenait un nul qui ne peut pas être une adresse de mémoire)et donc le système d'exploitation envoie un signal pour prévenir les invalides de fonctionnement de la mémoire et donc une erreur de segmentation se produit.
Dans le second cas, vous affectez l'adresse de la variable qui doit être mis à jour pour le pointeur et le stockage de la valeur qui est la bonne façon de faire, et donc il n'y a pas d'erreur de segmentation.
OriginalL'auteur Santhosh Pai
int une stocke une valeur entière aléatoire. Ce disant en disant *, vous pouvez accéder à un emplacement mémoire qui est en dehors des limites ou non valide. C'est donc un seg fault.
OriginalL'auteur Arvind Haran