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;
代碼正確執行。
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;
代碼正確執行。
它會給你一個分割錯誤,因爲你在做什麼是未定義的行爲。您正在訪問z
結構的指針,而不是對其進行初始化(即,不給它指向的內存空間)。在變量不是靜態的情況下,它不會給出分段錯誤並不重要,因爲對未初始化指針的整體訪問是錯誤的。
嚴格來說,由於'b'被聲明爲'static',所以保證被初始化爲零。 'b.z'保證是一個空指針。當然,行爲仍然是不確定的。 – AnT
您從未爲您的b.z
分配內存。您的b.z
包含未初始化的垃圾值,這就是爲什麼試圖廢除b.z
(在b.z->u
中)會導致分段錯誤的原因。
P.S.你宣佈你的對象static
,這意味着b.z
最初包含一個空值(不是「未初始化的垃圾值」,如上所述)。儘管如此,解引用空指針也是未定義的。
但分配給非靜態分配的工作? – karan
@karan:什麼是「非靜態分配」?如果你刪除'靜態'?不,它不「工作」。如果它沒有崩潰,那只是因爲你以某種方式得到了幸運,並且垃圾值最終指向了一些可寫的內存,隨後你就會破壞它。 – AnT
@karan - 不,它可能會出現*工作,但原因很微妙,事實是您的代碼有一個可怕的錯誤,因爲b.z永遠不會被初始化。奧利的回答很好。靜態的原因澄清你的bug是靜態保證零初始化變量。這將b.z設置爲NULL指針,並且會得到一個很好的,確定性的崩潰。當b被分配非靜態時,它從先前堆棧中的任何內容接收內容。在這種情況下,b.z可以獲得值NULL,或者一些非指針值或其他有效指針(然後使用b.z將覆蓋另一個指針的內存)。 –
因爲b.z
尚未設置爲指向任何有用的位置。它目前只是一個NULL
指針。 *
您需要的線沿線的做一些事情:
b.z = malloc(sizeof(*b.z));
第一(即創建一個實際的對象)。
請記住在free
這個點上。
*請注意,這只是因爲NULL
是b
聲明爲static
。如果b
不是static
,它將指向內存中隨機的某處。
Downvoter:關心評論? –
看起來像有人不喜歡這個問題,並想要每個人回答它。我想今天在Youtube上沒有什麼好處。 –
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;
爲什麼你的第二個例子的作品,我不知道。我懷疑這是由於'運氣'...
無法理解爲什麼它會以這種方式發生。也有任何其他的上述分配.. – karan
這個時候的每個答案都指出,b結果的靜態分配在bz中設置爲未定義的值。事實上,靜態保證零初始化內存,所以b.z是NULL。如果你刪除了關鍵字static,那麼你會得到一個更糟的錯誤,其中b.z指向內存中的某個隨機位置,也許argv被存儲的位置等。 –
@Heath Hunnicutt:不正確。首先,我的回答和評論從一開始就虛構了指針爲空。其他答案也是如此。其次,OP在其中一個評論中明確提出了關於同一事物的非靜態版本。 – AnT