簡體   English   中英

局部變量和數組將如何存儲在堆棧中?

[英]How will the local variables and arrays stored in stack?

[https://i.stack.imgur.com/kfU6n.png ][1]

#include<stdio.h>
int main()
{
    int x = 23;
    int y = 24;
    int z = 25;
    int asar= 26;
    int a[5];    
    int p = 15;
    int q = 16;
    int r = 17;
    a[11]=56;
    a[10]=57;
    a[9]=58;
    a[8]=59;
    a[7]=60;
    a[6]=61;
    a[5]=62;
  
    printf("\t x=%d, y=%d, z=%d,asar=%d, p=%d, q=%d, r=%d \n", x, y, z, asar, p, q, r);

    return 0;
}

我試圖越過數組的邊界,這會導致未定義的行為,但在這里我發現所有超出數組邊界的值都按最高索引值的順序復制
11被復制到x中(第一個聲明)
10被復制到y (第二次聲明)
9被復制到z中(第三次聲明)
8被復制到asar (第四次聲明)
7被復制到p中(第五次聲明)
6被復制到q中(第六次聲明)
5被復制到r中(第七次聲明)

除了a之外,總共還有 7 個其他變量,我已經將a限制恰好超過了7 個(4+7=11),我得到的輸出為: x=56,y=57,z=58,asar=59 , p=60, q=61, r=62
這背后有什么邏輯嗎?
不要驚訝我為什么考慮堆棧中的內存分配,因為除了a之外有7 個變量,超過7 個值被一個接一個地復制。 至少對於我來說,當額外變量的數量等於界限超出時,這在每種情況下都是正確的。
對此是否有任何合乎邏輯的解釋,或者這個問題毫無價值?

雖然auto變量幾乎總是存儲在堆棧中,但 C 標准並未強制執行此操作。

對於這樣一個沒有可變長度數組類型的對象[具有自動存儲持續時間] ,它的生命周期從進入與其關聯的塊開始,直到該塊的執行以任何方式結束。 (進入封閉的塊或調用函數會暫停,但不會結束當前塊的執行。)如果遞歸地進入塊,則每次都會創建對象的新實例。 對象的初始值是不確定的。 如果為對象指定了初始化,則在執行塊時每次到達聲明時都會執行該初始化; 否則,每次達到聲明時,該值變得不確定。

[6.2.4 對象的存儲期限,C11]

最符合描述的數據結構確實是堆棧,但標准中沒有定義,也沒有特定的順序來存儲變量。 CPU 通常要求數據以某種方式對齊以快速訪問它們,並且編譯器可能(並且將)重新排序它們以減少未使用的地址。 在代碼中的某處添加char可能會改變變量的內部順序。

此外,嘗試從其他對象地址訪問對象是未定義的行為。 即使你“幸運”並讓它以你想要的方式工作,它也可能在以后因為一些看似無關的原因而中斷。 例如,通過更改優化級別,編譯器可能會刪除或合並某些變量,或者將它們放在您無法訪問的寄存器中。 利用未定義的行為從來都不是一個好主意。

如果您需要確保數據的特定順序,您可以使用struct ,它的順序是有保證的。

正如 6.2.5 中所討論的,結構是由一系列成員組成的類型,其存儲按有序序列分配,而聯合是由一系列成員的存儲重疊組成的類型。

[6.7.2.1 結構和聯合說明符,C99]

通過struct對象指針訪問成員是有效的,但編譯器可以在成員之間插入填充。 offsetof()宏是正確訪問它們所必需的。 (相關:http: //www.catb.org/esr/structure-packing/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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