臨時變數在stcak中順序 gcc4 4

2021-05-24 08:32:08 字數 1205 閱讀 5481

朋友問我一道題他碰到的筆試題:

sizeof(b)求b所占用的空間,這個是3沒有問題。

strlen僅僅根據'/0'的出現判斷字串大小,而不管'/0'是不是出現在陣列之內。由於b的末尾沒有'/0',所以strlen(b)的值依賴於程式的記憶體布局。

我記得李先靜兄在《系統程式設計師成長計畫》裡提到過gcc對臨時變數的進棧順序處理,查了一下:

「gcc不同版本的處理是不一樣的,對於老版本的gcc(如gcc3.4),第乙個臨時變數放在最高的位址,第二個其次,依次順序分布。而對於新版本的gcc(如gcc4.3),臨時變數的位置是反的,即最後乙個臨時變數在最高的位址,倒數第二個其次,依次順序分布。」

不管是臨時變數在棧中的順序是遞增還是遞減,只要是有序的,那麼strlen(b)的值就應該是6,我估計這也是出題者在b的前後各放了乙個4位元組長的陣列的原因。

朋友驗證之後告訴我,他在gcc4.4.1下輸出是7 3,於是我做了下面的實驗,驗證臨時變數在stack中的排列順序:

unbuntu + gcc 4.4.1

輸出:bffff448 bffff444 bffff44d bffff440

7 3從記憶體布局可以看出,gcc調整了變數的順序,難道是為了32bit對齊所作的優化?

接著來,多定義了乙個char變數:

輸出:bffff448 bffff444 bffff44c bffff440

3 3果然是把新定義的char變數放到了b的後面,這些不對齊的變數放到了堆疊的高位址(先入棧)。

接著驗證:

輸出:bffff44c bffff448 bffff444 bffff440

7 4b也是32bit對齊後,變成了先定義的在堆疊高位址(先宣告先入棧)。

再來: 

輸出:bffff448 bffff444 bffff440 bffff43c

7 4再次加入char 型別變數之後,不是32bit對齊的char放在了堆疊的高位址處。

windows下用 codeblock + mingw(gcc 4.4.4)測試了一下題目的**:

堆疊裡的資料如下:

gcc4.4.4沒有優化32bit對齊,先宣告先入棧。

結論:

臨時變數在棧中的順序沒有強制規定,完全依賴於編譯器的實現,不應該對它做任何假設。

題外話:

這些沒有標準可查、像期末考試題一樣的筆試題不知道什麼時候才能消失。

C C 中的臨時變數

說到臨時變數,我們大家也許都挺熟悉,但是我自己對臨時變數的理解卻一直存在乙個誤區。通常情況下,我會把為了做某一件事情而臨時建立的乙個變數叫做臨時變數。比如說在交換兩個變數的值時,通常我們會建立第三個變數來達到我們最終的目的,而我們稱之為 臨時變數 然而,大師scott meyers告訴我們,事實不是...

程式設計中臨時變數的使用 20175204

提交 編譯執行沒有問題後,git add git commit m 陣列元素刪除,插入 git push 提交碼雲上你完成的 的鏈結。任務 定義乙個陣列,比如 int arr 列印原始陣列的值 for int i arr system.out.println 新增 刪除上面陣列中的5 列印出 1 2...

程式設計中臨時變數的使用 20175225

提交 編譯執行沒有問題後,git add git commit m 陣列元素刪除,插入 git push 提交碼雲上你完成的 的鏈結。任務 定義乙個陣列,比如 int arr 列印原始陣列的值 for int i arr system.out.println 新增 刪除上面陣列中的5 列印出 1 2...