2011-12-29 58 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