2011-12-29 66 views
4

有一些代碼,我閱讀和部位是:固定的指針語句?

public static unsafe byte[] GetBytes(uint value, bool BigEndian) 
    { 
     byte[] buff = new byte[4]; 
     fixed (byte* pbyte = buff)*((uint*)pbyte) = value; 
     if (BigEndian) 
      buff.EndianConvert(); 
     return buff; 
    } 

據我所知,它只是把4個字節的單元的位置到字節數組,但我不清楚如何。

我對它的理解是:

(byte* pbyte = buff) 

創建並返回一個字節的指針PBYTE,它指向的buff的地址,

(uint*)pbyte 

施放PBYTE的地址轉換爲UINT指針?,

我不明白,雖然它的其餘部分。固定關鍵字有什麼用處?爲什麼不能這樣做:

(byte* pbyte = buff) = (byte*)value; 

回答

1

其他人解釋釘扎的概念,但我覺得什麼讓你感到困惑的是,它是所有在一行。

fixed (byte* pbyte = buff)*((uint*)pbyte) = value; 

等同於:

fixed (byte* pbyte = buff) 
{ 
    *((uint*)pbyte) = value; 
} 

就像這樣:

if(someCondition) DoSomething(); 

等同於:

if(someCondition) 
{ 
    DoSomething(); 
} 

這是否清晰起來?現在應該很明顯,第一部分是變量聲明和相關的塊,第二部分是賦值。

+0

謝謝,這清除了它。我以爲這個聲明是表達的一部分.. – mowwwalker 2011-12-29 04:52:17

+0

@Walkerneo:說實話,它最初也把我扔了,而我(喜歡這樣認爲)我非常精通C#。我不得不在這條線上看兩次,缺乏空間使它非常難看。 – 2011-12-29 08:27:38

2

fixed語句阻止垃圾收集器重新定位一個可移動的變量。如果你忽略它,你的地址可能會得到改變,你會得到一個錯誤

1

你不能只取一個數組的地址,因爲它是由垃圾收集管理,這意味着其在內存中的位置可以在任何改變時間。 fixed關鍵字將數組固定在其作用域的持續時間內,從而允許數組的四個字節填充(4字節)uint值。

+0

聲明如何工作? – mowwwalker 2011-12-29 02:32:08

0

在CLR GC過程中,對於正常的GC堆對象(除LOH),GC將迎來與移動仍然存活的對象到下一代(這個動作也被命名推動)。當提升對象A時,GC會將對象A地址從addr-old修改爲addr-new,然後更新引用此對象的所有對象的關係。

例如,對象A被對象B和對象C引用,這意味着對象B具有指向對象A的指針,並且對象C也具有指向對象A的指針。然後,在對象A的地址將從addr-old改爲addr-new,然後,GC還將修改對象B和對象C的引用指針值。修改後,對象B和C具有仍然是正確的指針現在指向A.

在執行「byte * pbyte = buff」行之後,pbyte有一個指向對象「buff」的指針,假設pbyte地址是0x12345678(也就是說buff addr是0x12345678)。現在,GC發生了,對象「buff」將被提升爲新一代,這意味着對象「buff」將會有一個新的內存地址,例如「0x55555555」。但是,「pbyte」是一個本地(非託管)對象,CLR不知道如何維護它的生命週期,所以儘管pbyte與buff有關係,但CLR不能將pbyte地址從0x12345678更改爲0x55555555。然後,指針「pbyte」仍指向地址0x12345678,但該地址不屬於「buff」對象,指針「pbyte」現在是一個不好的指針。

「固定」的聲明將確保被管理對象「迷」不會被提升,也意味着不會從這裏搬到那裏。

+0

太棒了,謝謝!這解釋了固定的關鍵字,但我仍然不明白聲明的邏輯。它如何將值的地址分配給pbyte指針?它是如何工作的? – mowwwalker 2011-12-29 03:11:53

+0

該方法是GetBytes(uint值,bool BigEndian),第一個參數應該是一個uint值,它是一個4字節的對象。因此,該方法分配一個4字節的緩衝區,然後先將指針「pbyte」轉換爲uint *類型,然後將「value」賦值給該類型爲uint的地址。最後,這種方法將「不安全」緩衝區返回給其他不安全的方法使用。 – 2011-12-29 04:10:49