对于下面这两个简单的源文件,在a1.c
中初始化了一个全局数组,如果它在a2.c
中被称为数组,则程序运行正常。如果它被称为指针(当定义TEST
时),则发生分段错误。
本地数组和函数func()
用于比较。如果参数传递了指针,它运行正常。
$ cat a1.c
char s1[] = "abc";
$ cat a2.c
#include <stdio.h>
#ifdef TEST
extern char *s1;
#else
extern char s1[4];
#endif
void func(char *s2)
{
printf("s2: %s\n", s2);
}
int main(void)
{
printf("s1: %s\n", (char *)&s1); // ok for both cases
printf("s1: %s\n", s1); // Seg Fault if TEST is defined
char s2[] = "123";
func(s2);
return 0;
}
$ gcc -Wall a1.c a2.c && ./a.out
s1: abc
s1: abc
s2: 123
$ gcc -Wall -DTEST a1.c a2.c && ./a.out
s1: abc
[1] 112651 segmentation fault ./a.out
答案 0 :(得分:2)
考虑这些声明:
char a[1024];
char *a;
What happens when you write a[i] = j;?
对于前一种情况,编译器只选择一个内容的地址,在数组中,它是第一个元素的地址;缩放i,并将其加到基址。然后它会将存储j的地址的内容写入该地址。
对于后一种情况,它是完全不同的:编译器必须检查存储a的存储器位置,加载该存储器位置的内容,使用THAT作为地址,并将j的内容写入该地址。
现在%s格式说明符需要char *,现在你知道为什么分段错误.. :))