2010-07-11 66 views
4

当与gcc编译,然后运行, 代码全局指针会导致分段错误?

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

导致段故障。

显然,p中包含的内存位置 无法写入。

为什么?

在另一方面,

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

运行就好了。

这是怎么回事?

为什么p只包含只读存储器?

+4

但当然!所有导致分段错误的全局指针必须比对指针工作方式的轻微误解更有可能! – Thanatos 2010-07-11 23:23:49

回答

10

第一个示例具有一个百搭(未明确初始化)的指针。由于它不是自动变量,因此它被设置为0,这显然不是您拥有的内存。

printf("%p\n", p) 

至于第二个,C99§6.9.2实际上给这个作为一个例子:你可以通过它打印出来看到这

例2如果在 翻译结束单元包含

int i [];

阵列我仍然具有不完整的类型, 隐初始化使其 具有一个元件,其被设置为零 在程序启动。

一般来说,暂定定义(没有初始化)与0,这对于一个阵列装置与元件值的1个元素的数组0

+1

作为一名前C++开发人员,我仍然不得不问为什么* q = 1的作品“很好” - 运气? – 2010-07-11 23:24:37

+2

我觉得'gcc'的警告总结了一下:'警告:数组'q'假定有一个元素' - 不管这是有效的C,还是'gcc'都是慷慨的,我不确定。 – Thanatos 2010-07-11 23:30:14

+0

@Will A:因为他正在使用的编译器可能仍然为数组'q'分配一些内存或简单地指向内存中的可写部分(其中全局变量的其余部分被存储)。因为数组实际上没有被赋予大小,所以我会说这是未定义的行为,或者编译器不符合规范(我不确定它是在哪种情况下)。 – 2010-07-11 23:38:24

0

你的第一示例将导致一个分段错误,因为你被初始化对象正在取消引用NULL。你永远不会初始化p的值,而因为它是全局的它将为NULL。因此,你解除NULL和繁荣。

我不确定第二个例子是否有效 - gcc指出它假设q是一个1元素的数组,这就是为什么它不会爆炸。

3

*p = 1;会导致分段错误,因为它在分配前未分配任何内存。

*q = 1;因为编译器(Mac OS X上的gcc 4.2.1)警告假设q []有一个元素。