Pointeur-tableau-extern question

Fichier 1.c

int a[10]; 

Fichier main.c:

 extern int *a; int main() { printf("%d\n", a[0]); return 0; } 

Me donne un segfault! Qu’est-ce qui ne va pas?

Les tableaux se décomposent ou sont implicitement convertis en pointeurs lorsqu’ils sont passés à une fonction en tant qu’argument ou convertis en une valeur r sur le côté droit de l’opérateur d’affectation. Donc, quelque chose comme:

 int array[10]; int* a = array; //implicit conversion to pointer to type int void function(int* a); function(array); //implicit conversion to pointer to type int 

fonctionne très bien. Mais cela ne signifie pas que les tableaux eux-mêmes sont des pointeurs. Ainsi, si vous traitez un tableau comme un pointeur comme vous l’avez fait, vous traitez en fait le type de tableau comme s’il s’agissait d’un pointeur qui contenait l’adresse à un object int . Étant donné que votre tableau est en fait une séquence d’objects int , et non des pointeurs sur des objects int , vous essayez en réalité de déréférencer un emplacement de mémoire qui ne pointe pas vers un emplacement valide (le premier emplacement du array est une valeur entière numérique) comme 0 qui serait comme déréférencer un NULL). C’est pourquoi vous êtes en segfaulting. Notez que si vous aviez fait quelque chose comme ça:

 int array[] = { 1, 2, 3, 4, 5}; int b = *array; 

Cela fonctionne toujours, puisque array est à nouveau converti implicitement en un pointeur sur le bloc de mémoire contenant une séquence de valeurs entières et est ensuite déréférencé pour obtenir la valeur dans la première séquence. Mais dans votre cas, en déclarant votre tableau au module de code actuel en tant que pointeur défini de manière externe, et non en tant que tableau, il ignorera la conversion implicite en un pointeur qui est normalement effectué et utilisera simplement l’object tableau tel quel. étaient un pointeur sur un object lui-même, pas un tableau d’objects.

Bien expliqué dans la FAQ C. Et il y a un suivi . La photo dans le deuxième lien vaut un million de dollars.

 char a[] = "hello"; char *p = "world"; 

entrez la description de l'image ici

Réponse courte: utilisez extern int a[] .

Un peu tard, une copie de ce problème vient d’être entrée (et fermée). Les réponses ici ne mentionnent pas les fichiers d’en-tête …

Le problème serait résolu au moment de la compilation si vous placez la déclaration de array a dans un fichier d’en-tête, auquel elle appartient, au lieu de le placer dans le fichier .c. Le fichier d’en-tête doit ensuite être inclus dans les deux fichiers .c et le compilateur peut voir que ce que vous avez déclaré est faux.

Votre fichier d’en-tête contient:

 extern int myarray[]; 

Vous obtiendrez quelque chose comme ” error: conflicting types for a ” si vous déclarez plutôt un pointeur.

En gros, vous devez écrire votre main.c comme ceci:

 extern int a[]; int main() { printf("%d\n", a[0]); return 0; } 

Découvrez la sortie du code suivant.

Fichier1.c

 #include  extern int* my_arr; void my_print() { printf("%d", my_arr); } 

principal c

 #include  int my_arr[2] = {1,2}; extern void my_print(); void main() { my_print(); } 

sortie

 1 

Dans File1.c, my_arr est une variable de pointeur ayant la valeur 1. ce qui signifie que le premier élément de my_arr [] lui a été atsortingbué. Ensuite, si vous utilisez * my_arr pour accéder à l’emplacement de mémoire ox1, vous obtenez une erreur de segmentation car vous n’êtes pas autorisé à accéder à ox01.

Pourquoi le pointeur my_arr a-t-il été affecté 1 (premier élément de my_arr [])?

Cela concerne le fonctionnement de l’assembleur. Lire cet article

Pourquoi votre code ne peut pas accéder à 0x01?

Je sais que cela a à voir avec le système d’exploitation ne permettant pas l’access à un espace d’adressage par code utilisateur. C’est tout ce que je sais. google si vous voulez plus d’informations.