2014-03-04 90 views
0
unsafe static void Main(string[] args) 
    { 
     int i=6; 
     int* j = &i; //Allowed 
     int* k = j; //Allowed 
     fixed(int* q = &i) //Allowed 
     { 
     } 
     fixed(int* q = j) //Cannot declare pointer to non unmanaged type int* 
     { 
     } 
    } 

我对第2个固定块的操作与我在第一个固定块中所做的操作基本相同。 我将一个变量i的地址赋值给一个指针q。直接地址分配是允许的,同时在另一个指针中使用地址并在分配中使用该指针失败。然而,在固定环境之外,相同的步骤仍然有效。发生了什么事?无法将指针指向非非托管类型int * C#

+2

你确定这是错误文本吗?请剪切并粘贴确切的文字。 –

+0

第一个固定块对我来说是无效的......“你不能使用固定语句来获取已经固定的表达式的地址”。请发布您的确切代码。 –

回答

0

您使用的是什么版本的C#?第一个fixed声明也不会为我编译(You cannot use the fixed statement to take the address of an already fixed expression)。

修复非托管指针没有意义。它已经修复了,它不能被GC触及。

例如,当您使i成为类的成员字段时,此更改。突然之间,它不再是该方法的范围,并且可以通过GC(以及它的计数对象)移动。在这种情况下,您使用fixed语句。

编译器不允许您将指针指向未固定的托管变量,并且它不会允许您修复非托管或固定变量。

同样的方法,如果你把一个指针指向一个数组的开始,例如。使int[] i,并采取&i[0],它再次需要修复,因为它不再保证本地作用域。如果您确实需要一个本地范围的非托管阵列,则可以使用stackalloc关键字,但这又意味着您正在削减受管.NET的相对安全性。

0

The fixed statement用于一个托管变量,以便垃圾回收器不会移动它。

在正常操作中,垃圾收集器可自由移动物体。这对于指针来说是一个问题,因为如果垃圾收集器移动了一个指向的对象,指针将不再有效。 fixed通过让你引脚为变量提供了一个解决方案,告诉垃圾收集器指向该对象的指针可能存在,并且它不能在代码块的持续时间内移动它们。

C#编译器只允许您在固定语句中指定托管变量的指针。

堆栈(值类型)上分配的变量不受垃圾收集器,并且将不在存储器中移动,所以fixed既不必要的和不正确这样的变量。这就是为什么你的第二个(也是你的第一个)fixed声明产生一个错误。

相关问题