I want to use variable a from foo.c in main.c, and I write:
foo.c
#include <stdio.h>
int a[] = {3, 2};
void foo()
{
printf("foo\taddress of a:%x\n", a);
printf("foo\tvalue of a[0]:%x\n", a[0]);
}
main.c
#include <stdio.h>
extern int *a;
int main(void)
{
foo();
printf("main\taddress of a : %x\n", a);
printf("main\tvalue of a[0] : %x\n", a[0]);
return 0;
}
and the result output:
foo address of a:804a014
foo value of a[0]:3
main address of a : 3
Segmentation fault (core dumped)
why?
The type of
aisint[2], notint*. Try again withThe C compiler cannot type-check across source files. Therefore, when you say
int* a, the compiler will assume you’re telling the truth, use pointer semantics, and will not issue any compiler error.There are subtle difference between arrays and pointers. Let’s assume a 32-bit system. Then the content of “a” will be distributed like this:
a 0x100 0x104 0x108 ← address +-----------+----------+ | 3 | 2 | ← content +-----------+----------+When
ais an array,ais will be converted to the address ofa. Therefore, when you printa, you will get its address, i.e. “0x100”.a[n]in C is equivalent to*(a + n), i.e. advance the addressabynunits, and then dereference it to get the content. Therefore,a[0]is equivalent to*0x100, which returns the content at 0x100, i.e. “3”.When
ais a pointer,ais the content at the provided address. In fact this is the norm, the array type is a special case. Therefore, when you printa, you will get the content at that address, i.e. “3”.a[n]is still*(a + n). Therefore,a[0]is equivalent to*3, which causes segmentation fault because the address “3” is invalid.