C#中不安全代码的编写和指针的应用

关键字:托管代码managed code, 不安全代码unsafe code, 固定托管指针fixed, 在stack上分配空间stackalloc

Managedd Code和UnManaged Code
    运行在公共语言运行库 (CLR) 的控制之下的代码称为“托管代码”,运行在 CLR 之外的代码称为“非托管代码”。COM、COM+、C++ 组件、ActiveX 组件和 Win32 API 都是非托管代码的示例。

概念1:安全代码safe code和不安全代码unsafe code的概念
        所谓安全代码,是指由CLR进行托管并进行安全性验证的代码。在安全代码中,我们无法进行内存的直接操作,因为所有内存heap是托管堆(managed heap)。 但是有些应用中,仍然需要对内存的直接操作,这时候就需要将代码标记为不安全代码unsafe。
        不安全代码就是无法通过CLR进行安全验证的代码,其安全性由自己负责保证代码不会引起安全风险或指针错误。
        凡是需要操作指针的代码都必须标记为非安全代码。
        不安全代码的关键字为unsafe.
        注意:在 C# 中,为了编译不安全代码,必须用
/unsafe 编译应用程序。


概念2:fixed关键字的应用
    在托管框架下,我们知道,所有reference type的instance在托管heap中的地址不是固定的,他们要随着GC的不断回收内存,托管对象也要在generational Garbage Collector 0,1,2之间移动。那么如果我们编写不安全代码,如何用指针指向某个托管对象呢?
    唯一的方法就是:将托管堆中的该对象固定住!这就是我们的关键字fixed。也就是要将所要指向的托管对象固定住。

    int[] a=new int[10];
    unsafe
    {
        
fixed(int *p=a) //将a 固定住!
        {
            对指针p进行操作......
        }
    }

概念3:在堆栈上动态分配空间 stackalloc
        在unsafe context下,我们可以在stack上动态分配内存块。因为该申请到的内存块不属于托管堆,不会受到GC的制约,内存块的生存期受定义它的方法的生存期的限制。因此,该内存块不需要被
固定住(fixed)
  
  例如:
    public unsafe void Test
    {
   
 int *p=stackalloc int[100];
    /*
    在stack(注意:不是managed heap!!切记)上申请了一段长100个整数的数组,p指向该数组的首地址。
    */
    
int [] q=new int [100];
    /*
    q就是在managed heap上申请的空间,如果此时有一个指针指向q,就必须将其固定住
    
fixed(int *p1=q)
    {
    }
*/
  }

概念4:C#中的各种指针类型
示例 说明

int* p

p 是指向整数的指针

int** p

p 是指向整数的指针的指针

int*[] p

p 是指向整数的指针的一维数组

char* p

p 是指向字符的指针

void* p

p 是指向未知类型的指针



  

你可能感兴趣的:(C#)