[英]pointer to a structure
即使我尚未分配內存並聲明了一個指向main內部結構2的指針,這也將提供適當的輸出
struct one
{
char x;
int y;
};
struct two
{
char a;
struct one * ONE;
};
main()
{
struct two *TWO;
scanf("%d",&TWO->ONE->y);
printf("%d\n",TWO->ONE->y);
}
但是當我在main外部的結構之后聲明一個指向2的指針時,我將得到分段錯誤,但是為什么在以前的情況下我沒有得到分段錯誤
struct one
{
char x;
int y;
};
struct two
{
char a;
struct one * ONE;
}*TWO;
main()
{
scanf("%d",&TWO->ONE->y);
printf("%d\n",TWO->ONE->y);
}
在這兩種情況下, TWO
都是指向 struct two
類型的對象的指針 。
在情況1中,指針是野生的,可以指向任何地方。
在情況2中,指針是NULL
因為它是全局的。
但是在兩種情況下,它都沒有指向有效的 struct two
對象的指針。 您在scanf
代碼會將這個指針當作指向有效對象一樣對待。 這導致未定義的行為。
因為您正在做的事情是不確定的行為。 有時似乎可行。 這並不意味着您應該這樣做:-)
最可能的解釋與變量的初始化方式有關。 當堆棧指針遞減時,自動變量(在堆棧上)將獲得碰巧在堆棧上的所有垃圾。
函數外部的變量(如第二種情況)始終初始化為零(指針類型為空指針)。
這是您的兩種情況之間的基本區別,但是,正如我所說,第一種情況純粹是出於偶然。
聲明全局指針時,它將被初始化為零,因此生成的地址將是較小的數字,在您的系統上可能無法讀取。
聲明自動指針時,其初始值可能會更有趣。 在這種情況下,它將是調用main()之前在堆棧上的那個剩余運行時庫,或者是編譯器生成的堆棧框架設置代碼中的剩余值。 它可能是保存的堆棧指針或幀指針,如果與小偏移量一起使用,則是有效的指針。
因此,無論如何,未初始化的指針中確實包含某些內容,一個值導致錯誤,而到目前為止,系統上的另一個值卻沒有。
那是因為分段錯誤是OS的機制,而不是C語言的機制。
故障是一種基於塊的機制,可以為自身和其他程序分配一定數量的頁面(每個頁面數K),並在允許程序自由運行的同時保護自身和其他程序的頁面。 您必須在塊上下文之外迷路,或者嘗試編寫一個只讀頁面(即使您的頁面也是這樣)以生成錯誤。 僅僅打破語言規則並不一定足夠。 操作系統很樂意讓您的程序由於其狂野的引用而行為異常,並采取奇怪的行動,只要它本身僅讀取和寫入(或復制)它們即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.