2009-08-12 15 views
4

鑑於以下情況:byte [] sData;和聲明爲私人字節[] construct_command()函數什麼樣的內存語義管理在C#中的數組賦值?

如果我然後分配construct_command()結果SDATA 將SDATA只是點到了什麼從返回的真實內容函數還是會爲內存中的sData分配一些空間,並將函數結果的內容複製到內存中?

回答

2

假設SDATA是一個局部變量,它將生活在堆棧,這將參照由該方法返回的數組。該方法不返回數組本身的內容,而是返回數組的引用。

在.net中,數組是第一類對象,所有數組類型變量實際上都是引用。

2

sData將指向函數返回的內容。 C#中的數組是引用類型,這意味着從另一個數組中分配一個數組只需複製引用而不是分配新數據。

6

該分配將簡單地分配sData來引用由construct_command返回的實例。不會發生數據複製。

在一般情況下,CLR打破了世界分成兩種類型

  • 值類型:這是什麼,從System.ValueType派生。這些類型的值之間的賦值通過值發生,並且實質上導致位置之間的值的副本
  • 引用類型:其他。這些類型的值之間的賦值只會導致位置引用內存中的不同對象。沒有發生數值複製

數組是CLR中的引用類型,因此不會導致基礎值的複製。

+0

那麼這是否意味着在包含局部變量(sData)的方法返回之前內容被破壞的危險? – 2009-08-12 14:49:37

+1

不,因爲垃圾收集器會知道數組仍然被引用。 – 2009-08-12 14:50:32

0

sData將指向由construct_command返回的數組。

2

數組是一個引用類型,因此只複製引用。沒有內容操作。

3

數組是指引用類型,這意味着實際的數組在堆上實例化(可能由construct_command())並且該函數返回對數組的引用,並將其存儲在(本地變量)sData中。

所以這不是關於內存語義(返回值可能爲空),而是關於引用類型的複製語義。這種情況是完全相等,例如:

StreamReader reader = System.IO.File.OpenText(filename); 

說得更多一點不客氣地說:在.net中,您不能傳遞一個數組的一切,你只能傳遞,複製和分配給數組引用。

0

儘管Rui的回答總體上不錯,但我確實認爲它的一部分是不正確的。從堆棧內存中分配數組並沒有意義(非常不一致),然後通過引用進行訪問。如果這是真的,則可以從參考被傳遞給的任何方法下面釋放底層存儲器。

相信亨克Holterman正確地描述它,當他非常直接且明確地說:

數組是引用類型,這意味着實際的陣列 實例化在堆上

謝謝你對這個評論很感激;我認爲這是一個非常關鍵的部分,否則就會被接受的答案所遺漏(並且與之相矛盾)。

(我會回覆一條評論,但我沒有足夠的回覆點,我認爲足夠重要的是要指出接受的答案有這個問題,我想在這裏添加一條新評論。)也許管理員可以從答案中刪除對「本地變量,它將存在於堆棧中」的引用。