2010-07-11 5 views
4

Lorsque compilé par gcc puis exécutez, le codeLes pointeurs globaux provoquent une erreur de segmentation?

 
    int *p; 
    int main() {*p = 1;} 

provoque une erreur de segmentation.

Apparemment, l'emplacement de mémoire contenu dans p ne peut pas être écrit.

Pourquoi ????

D'autre part,

 
    int q[]; 
    int main() {*q = 1;} 

fonctionne très bien.

Que se passe-t-il ici ??

Pourquoi p contient-il uniquement de la mémoire en lecture seule?

+4

Mais bien sûr! Tous les pointeurs globaux causant des fautes de segmentation doivent être plus probables qu'un léger malentendu sur le fonctionnement des pointeurs! – Thanatos

Répondre

10

Le premier exemple a un pointeur sauvage (non explicitement initialisé). Comme ce n'est pas une variable automatique, elle est définie sur 0, ce qui n'est clairement pas votre mémoire. Vous pouvez voir cela en imprimant avec:

printf("%p\n", p) 

Quant à la seconde, C99 §6.9.2 donne en fait comme un exemple:

Exemple 2 Si à la fin de la traduction unité contenant

int i [];

le tableau I a toujours un type incomplet, l'initialiseur implicite lui fait ont un élément, qui est mis à zéro au démarrage du programme.

En général, les objets avec une définition provisoire (pas d'initialisation) sont initialisés avec 0, qui, pour un tableau signifie un tableau 1 élément avec valeur de l'élément 0.

+1

En tant que développeur ex-C++, je dois encore poser la question de savoir pourquoi le * q = 1 fonctionne "bien" - chance? –

+2

Je pense que l'avertissement de 'gcc' le résume:' warning: array 'q' supposé avoir un élément' - que ce soit C valide, ou simplement 'gcc' étant généreux, je ne suis pas sûr. – Thanatos

+0

@Will A: Parce que le compilateur qu'il utilise attribue probablement toujours le tableau 'q' avec de la mémoire ou simplement une position en mémoire (avec 0 éléments) qui pointe vers une section inscriptible de la mémoire (où le reste des variables globales sont stockés). Parce que le tableau n'a pas réellement été donné une taille, je dirais que c'est un comportement non défini, ou le compilateur n'est pas conforme (je ne suis pas sûr de ce que c'est dans ce cas). –

0

Votre premier exemple provoque une erreur de segmentation parce que vous sont déréférencement NULL. Vous n'initialisez jamais p avec une valeur, et parce que c'est un global il sera NULL. Ainsi, vous déréférence NULL, et boom. Je ne suis pas sûr comment le deuxième exemple est valide - gcc note qu'il suppose q pour être un tableau à 1 élément, ce qui explique pourquoi cela ne va pas exploser.

3

*p = 1; provoque une erreur de segmentation car aucune mémoire n'a été allouée avant l'affectation.

*q = 1; fonctionne parce que le compilateur (gcc 4.2.1 sur Mac OS X) avertit que q [] est supposé avoir un élément.

Questions connexes