2010-07-11 68 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 []有一個元素。