[英]Cannot declare pointer to non unmanaged type int* C#
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*
{
}
}
我对第二个固定块的操作与我对第一个固定块的操作几乎相同。 我将变量i的地址分配给指针q。 允许直接地址分配,而在另一个指针中获取地址并在分配中使用该指针失败。 但是,在固定上下文之外,同样的步骤也起作用。
您正在使用什么版本的C#? 第一个fixed
语句也不适合我编译( You cannot use the fixed statement to take the address of an already fixed expression
)。
修复非托管指针没有任何意义。 它已经修复,GC永远无法触及。
例如,当您使i
成为类的成员字段时,这种情况就会更改。 突然,它不再受方法限制, 可以由GC(及其计数对象)移动。 在这种情况下,您必须使用fixed
语句。
编译器不允许您使用指向未修复的托管变量的指针,也不允许您修复未托管或修复的变量。
以同样的方式,如果您将指针指向数组的开头,例如 make int[] i
并取&i[0]
,这又需要修复,因为不再保证它是本地范围的。 如果确实需要本地范围内的非托管数组,则可以使用stackalloc
关键字,但是再次,这基本上意味着您要从托管.NET的相对安全中stackalloc
。
该fixed
语句用来钉住管理变量,因此垃圾回收不会动它。
在正常操作中,垃圾收集器可以自由移动对象。 这对于指针将是一个问题,因为如果垃圾回收器将您有指针的对象移动到该指针,则该指针将不再有效。 fixed
为您提供了解决方案,方法是让您固定变量,告诉垃圾回收器该对象的指针可能存在,并且在代码块的持续时间内不得移动它们。
C#编译器仅允许您在固定语句中将指针分配给托管变量。
分配在堆栈上的变量(值类型)不受垃圾收集器的约束,并且不会在内存中移动,因此,对于此类变量而言, fixed
既不必要又不正确。 这就是为什么您的第二个(实际上也是第一个) fixed
语句产生错误的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.