首頁 >後端開發 >C++ >堆疊或堆疊:「new」在哪裡為 C# 結構分配記憶體?

堆疊或堆疊:「new」在哪裡為 C# 結構分配記憶體?

DDD
DDD原創
2025-01-13 15:16:41688瀏覽

Heap or Stack: Where Does `new` Allocate Memory for a C# Struct?

C# 中使用 "new" 關鍵字建立結構體時,記憶體分配在堆疊還是堆疊上?

使用 "new" 運算子建立類別實例時,記憶體分配在堆上。但使用 "new" 運算子建立結構體實例時,記憶體分配在哪裡呢?

堆疊記憶體與堆疊記憶體

堆疊是一種用於在程式執行期間​​儲存局部變數和方法呼叫的資料結構。它是一種後進先出 (LIFO) 結構,這意味著最近分配的記憶體最先被移除。

堆是一個動態記憶體空間,根據需要建立和分配物件。與堆疊不同,它不遵循記憶體分配的特定順序。

使用 "new" 關鍵字建立結構體的記憶體分配

對於結構體,使用 "new" 運算子時,需要考慮兩種情況:

  1. 無參數建構子 (new Guid();):

    • 使用 "new" 運算子和無參數建構子會在 上分配結構體的記憶體。
    • 這是因為 C# 編譯器將無參數建構函式視為一種特殊情況,將其視為零初始化運算。
    • 因此,會在堆上建立一個新的記憶體位置,並在其中建構結構體。
  2. 帶參數建構子 (new Guid(someString);):

    • 使用 "new" 運算子和帶參數建構子會在 上分配記憶體以進行暫存。
    • 建構函式初始化結構體後,分配的堆疊記憶體將被丟棄。
    • 此過程與將實例化的結構體賦值給局部變數不同,後者會在堆上分配內存,就像無參數構造函數一樣。

IL 程式碼產生

為了理解幕後行為,讓我們檢查 C# 編譯器產生的中間語言 (IL) 程式碼:

  • newobj 指令在堆疊上分配空間並為中間值(例如,方法參數)呼叫帶參數的建構子。
  • call instance 指令使用帶參數的建構子初始化已指派的儲存位置(堆疊或堆疊)。
  • initobj 指令初始化已指派的儲存位置(堆疊或堆疊),將其內容清除(用於無參數建構函式呼叫)。

結論

總之,與始終在堆上分配內存的類別實例不同,對結構體使用"new" 運算符會在無參數構造函數的情況下在堆上分配內存,在帶參數構造函數的情況下在棧上分配記憶體(用於暫存)。此行為反映在生成的 IL 程式碼中,並提供了對底層記憶體管理過程的深入了解。

以上是堆疊或堆疊:「new」在哪裡為 C# 結構分配記憶體?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn