簡體   English   中英

指向結構的指針

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM