C#基礎—不安全代碼(unsafe code)

1.爲什麼要有unsafe程序員

    也許是爲了實現CLR類型安全的目標吧,默認狀況下,C#沒有提供指針的使用算法,可是有些狀況下也可能須要指針這樣直接訪問內存的東西(雖然目前我尚未用過),可是有時候程序員很是清楚程序的運行情況,須要使用指針直接訪問內存以便於提升性能或者調試、監控程序運行的內存的使用情況,以便於採起相應的措施。還有一些狀況是當咱們須要調用外面DLL中的函數又不能使用DllImport 時,也須要指針來傳遞這些函數。算法

2.unsafe 的定義安全

    MSDN:unsafe 關鍵字表示不安全上下文,該上下文是任何涉及指針的操做所必需的。函數

    其實,意思就是要使用指針前,請用unsafe 聲明下,可使類、方法,成員,類全局變量和代碼段,但不能修飾成員函數內部的局部變量,具體爲何不清楚,還望大神指點。性能

  在使用unsafe以前,咱們必須先看一段MSDN的話:在公共語言運行時 (CLR) 中,不安全代碼是指沒法驗證的代碼。 C# 中的不安全代碼不必定是危險的;只是其安全性沒法由 CLR 進行驗證的代碼。 所以,CLR 只對在徹底受信任的程序集中的不安全代碼執行操做。 若是使用不安全代碼,由您負責確保您的代碼不會引發安全風險或指針錯誤。操作系統

    所以,咱們在運行unsafe 代碼是要在項目屬性-生成選項裏配置下"容許運行不安全代碼"。先看下簡單的例子:指針

unsafe static void ChangeValue(int* pData)
{
   *pData = 200; //修改所在地址值
}調試


unsafe static void Main()
{
   int data = 100;
  Console.WriteLine("原始值: {0}", data);
  ChangeValue(&data); //取data地址並傳遞
  Console.WriteLine("改變地址後: {0}", data);內存

  Console.ReadLine();
}it

程序輸出:  原始值:100 ;  修改地址後:200

 

三、引入fixed

      當咱們討論fixed的時候,不得不先了解下,託管代碼和非託管代碼,所謂託管代碼就是由CLR去執行的代碼而不是操做系統去執行的代碼,而非託管代碼就是繞過CLR,由操做系統直接執行,它有本身的垃圾回收、類型安全檢查等服務。

      而不安全代碼就是容許本身使用指針訪問內存,但同時又要使用CLR提供的垃圾回收機制、類型安全檢查等服務,有的資料認爲是介於CLR和非託管代碼之間的一種代碼運行機制,也能夠理解。

      正由於如此,咱們自定義的指針地址就有可能被CLR垃圾回收機制從新調整位置,因此就引入了fixed ,MSDN對fixed的解釋是:fixed 語句設置指向託管變量的指針,並在執行該語句期間"固定"此變量。這樣就能夠防止變量的重定位。

      看下代碼的演示:

class PointerDemo{  public int x, y;}class Program{  unsafe static void ChangeValue(int* x, int* y)  {    *x = 200; //修改所在地址值    *y = 300;  }  unsafe static void Main()  {    var obj = new PointerDemo();    Console.WriteLine("原始值: {0}, {1}", obj.x, obj.y);     fixed (int* n = &obj.x)    {      fixed (int* p = &obj.y)      {        ChangeValue(n, p); //取data地址並傳遞      }    }    Console.WriteLine("改變地址後: {0}, {1}", obj.x, obj.y);     Console.ReadLine();   }}

相關文章
相關標籤/搜索