当用gcc编译然后运行时, 代码
int *p; int main() {*p = 1;}
导致分段错误。
显然,内存位置 p中包含的内容无法写入。为什么????
另一方面,
int q[]; int main() {*q = 1;}
运行得很好。
这里发生了什么?
为什么p只包含只读内存?
答案 0 :(得分:10)
第一个示例有一个wild(未显式初始化)指针。由于它不是自动变量,因此设置为0,这显然不是您拥有的内存。您可以通过以下方式将其打印出来:
printf("%p\n", p)
至于第二个,C99§6.9.2实际上是以此为例:
示例2如果在结束时 翻译单位包含
int i [];
数组我仍然有不完整的类型, 隐式初始化器导致它 有一个元素,设置为零 在程序启动时。
通常,具有暂定定义的对象(无初始化程序)初始化为0,对于数组,这意味着具有元素值0的1元素数组。
答案 1 :(得分:3)
*p = 1;
导致分段错误,因为在分配之前没有分配任何内存。
*q = 1;
有效,因为编译器(Mac OS X上的gcc 4.2.1)警告q []假定有一个元素。
答案 2 :(得分:0)
您的第一个示例导致分段错误,因为您正在取消引用NULL。您永远不会使用值初始化p
,而因为它是全局它将为NULL。因此,你取消引用NULL,并且繁荣。
我不确定第二个例子是如何有效的 - gcc指出它假设q
是一个1元素数组,这就是为什么它不会爆炸。