繁体   English   中英

无法声明指向非非托管类型int * C#的指针

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM