2011-09-16 232 views
1
struct x { 
    int *u; 
}; 

struct y { 
    struct x *z; 
}; 

int main() 
{ 
    static y b; 
    static int g=7; 
    b.z->u=&g; 
} 

語句b.z->u=&g給出了分段錯誤。如果我刪除static前面的int g通過嵌套結構訪問指針

int g=7; 
b.z->u=&g; 

代碼正確執行。

+0

無法理解爲什麼它會以這種方式發生。也有任何其他的上述分配.. – karan

+2

這個時候的每個答案都指出,b結果的靜態分配在bz中設置爲未定義的值。事實上,靜態保證零初始化內存,所以b.z是NULL。如果你刪除了關鍵字static,那麼你會得到一個更糟的錯誤,其中b.z指向內存中的某個隨機位置,也許argv被存儲的位置等。 –

+1

@Heath Hunnicutt:不正確。首先,我的回答和評論從一開始就虛構了指針爲空。其他答案也是如此。其次,OP在其中一個評論中明確提出了關於同一事物的非靜態版本。 – AnT

回答

1

它會給你一個分割錯誤,因爲你在做什麼是未定義的行爲。您正在訪問z結構的指針,而不是對其進行初始化(即,不給它指向的內存空間)。在變量不是靜態的情況下,它不會給出分段錯誤並不重要,因爲對未初始化指針的整體訪問是錯誤的。

+1

嚴格來說,由於'b'被聲明爲'static',所以保證被初始化爲零。 'b.z'保證是一個空指針。當然,行爲仍然是不確定的。 – AnT

1

您從未爲您的b.z分配內存。您的b.z包含未初始化的垃圾值,這就是爲什麼試圖廢除b.z(在b.z->u中)會導致分段錯誤的原因。

P.S.你宣佈你的對象static,這意味着b.z最初包含一個空值(不是「未初始化的垃圾值」,如上所述)。儘管如此,解引用空指針也是未定義的。

+0

但分配給非靜態分配的工作? – karan

+1

@karan:什麼是「非靜態分配」?如果你刪除'靜態'?不,它不「工作」。如果它沒有崩潰,那只是因爲你以某種方式得到了幸運,並且垃圾值最終指向了一些可寫的內存,隨後你就會破壞它。 – AnT

+1

@karan - 不,它可能會出現*工作,但原因很微妙,事實是您的代碼有一個可怕的錯誤,因爲b.z永遠不會被初始化。奧利的回答很好。靜態的原因澄清你的bug是靜態保證零初始化變量。這將b.z設置爲NULL指針,並且會得到一個很好的,確定性的崩潰。當b被分配非靜態時,它從先前堆棧中的任何內容接收內容。在這種情況下,b.z可以獲得值NULL,或者一些非指針值或其他有效指針(然後使用b.z將覆蓋另一個指針的內存)。 –

2

因爲b.z尚未設置爲指向任何有用的位置。它目前只是一個NULL指針。 *

您需要的線沿線的做一些事情:

b.z = malloc(sizeof(*b.z)); 

第一(即創建一個實際的對象)。

請記住在free這個點上。


*請注意,這只是因爲NULLb聲明爲static。如果b不是static,它將指向內存中隨機的某處。

+0

Downvoter:關心評論? –

+0

看起來像有人不喜歡這個問題,並想要每個人回答它。我想今天在Youtube上沒有什麼好處。 –

2

b.z尚未初始化。您初始化b有:

static y b; 

但其成員場z仍然是一個空指針(指向這樣一些隨機的位置)。因此,訪問其成員u會導致分段錯誤,因爲您正在訪問一些隨機存儲器。

我想,這應該工作(沒有嘗試):

static y b; 
static x c; 
static int g=7; 
b.z = &c; 
b.z->u=&g; 

爲什麼你的第二個例子的作品,我不知道。我懷疑這是由於'運氣'...