zoukankan      html  css  js  c++  java
  • c# 指针unsafe/fixed -- 【一】

    1.1 概述

    unsafe关键字表示不安全上下文,该上下文是任何涉及指针的操作所必需的。可以在属性、方法、类的声明中使用unsafe修饰符,此时类型或成员的整个正文范围均被视为不安全上下文。

    fixed语句用于禁止垃圾回收器重定位可移动的变量,Fixed还可用于创建固定大小的缓冲区,fixed 语句只能出现在不安全的上下文中。

    但在C#中使用指针时只能操作struct,不能操作class,不能在泛型类型代码中使用未定义类型的指针。

    在C#中编译不安全代码时,必须指定/unsafe编译器选项,否则无法通过公共语言运行库验证不安全代码,选择项目—属性—生成标签,勾选 “允许不安全代码”选项即可。

    c# <wbr>使用指针*&(unsafe <wbr>fixed)

    1.2 unsafe

    可以方法或属性上加入unsafe关键字: 

     C# Code 
    1
      unsafe void Fun(byte* ps, byte* pd, int count)


     也可在classstruct上加上unsafe关键字: 

     C# Code 
    1
      unsafe class Demo

     

    还可以使用不安全块,从而可以使用该块内的不安全代码。例如: 

     C# Code 
    1
    2
    3
    4
      // Unsafe context: can use pointers here.
    }

     

    完整示例如: 

     C# Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      static void SquarePtrParam(int *p)
    {
        *p *= *p;
    }

    unsafe static void Main()
    {
        int i = 5;
        SquarePtrParam(&i);
        Console.WriteLine(i);
    }

     

    1.3 fixed

    fixed语句可用于设置指向托管变量的指针并在statement 执行期间“钉住”该变量。如果没有fixed语句,则指向可移动托管变量的指针的地址可变,因为垃圾回收可能不可预知地重定位变量。

    C#编译器只允许在fixed 语句中分配指向托管变量的指针,但无法修改在fixed语句中初始化的指针。

    可以用数组或字符串的地址初始化指针: 

     C# Code 
    1
    2
      int* p = arr) ...  // equivalent to p = &arr[0] 
    fixed (char* p = str) ... // equivalent to p = &str[0]

     

    只要指针的类型相同,就可以初始化多个指针: 

     C# Code 
    1
      byte* ps = srcarray, pd = dstarray) {...}

     

    要初始化不同类型的指针,只需嵌套fixed 语句: 

     C# Code 
    1
    2
    3
    4
    5
    6
    7
      int* p1 = &p.x) 

        fixed (double* p2 = &array[5]) 
        { 
            // Do something with p1 and p2. 
        } 


    完整示例: 

     C# Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    class Point
    {
        public int x, y;
    }

    class FixedTest
    {
        unsafe static void SquarePtrParam (int *p)
        {
            *p *= *p;
        }

        unsafe static void Main()
        {
            Point pt = new Point();
            pt.x = 5;
            pt.y = 6;

            fixed (int *p = &pt.x)
            {
                SquarePtrParam (p);
            }

            Console.WriteLine ("{0} {1}", pt.x, pt.y);
        }
    }

     

    在不安全模式中,可以在堆栈上分配内存,而堆栈不受垃圾回收的制约,因此不需要被锁定,如栈内存(栈内存开辟快速高效但资源有限): 

     C# Code 

    1
    2
    3
    4
    5
    6
    7
    8
      unsafe void Fun()
    {
        int *p = stackalloc int[10];
        for (int i = 0; i < 10; i++)
        {
            p[i] = 2 * i + 2;
        }
    }
  • 相关阅读:
    hadoop中namenode发生故障的处理方法
    开启虚拟机所报的错误:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary fil
    Hbase的安装与部署(集群版)
    分别用反射、编程接口的方式创建DataFrame
    用Mapreduce求共同好友
    SparkSteaming中直连与receiver两种方式的区别
    privot函数使用
    Ajax无刷新显示
    使用ScriptManager服务器控件前后台数据交互
    数据库知识
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/4033546.html
Copyright © 2011-2022 走看看