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


1.為何要有unsafe

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

2.unsafe 的定義

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

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

  在使用unsafe之前,我們必須先看一段MSDN的話:在公共語言運行時 (CLR) 中,不安全代碼是指無法驗證的代碼。 C# 中的不安全代碼不一定是危險的;只是其安全性無法由 CLR 進行驗證的代碼。 因此,CLR 只對在完全受信任的程序集中的不安全代碼執行操作。 如果使用不安全代碼,由您負責確保您的代碼不會引起安全風險或指針錯誤。

    因此,我們在運行unsafe 代碼是要在項目屬性-生成選項里配置下"允許運行不安全代碼"。先看下簡單的例子:

 1 unsafe static void ChangeValue(int* pData)
 2 {
 4     *pData = 200; //修改所在地址值
 6 }
 7 
 8 
 9 unsafe static void Main()
10 {
12     int data = 100;
13     Console.WriteLine("原始值: {0}", data);
14     ChangeValue(&data);    //取data地址並傳遞
15     Console.WriteLine("改變地址后: {0}", data);
16 
17     Console.ReadLine();
18 }

程序輸出:

原始值:100

修改地址后:200

3、引入fixed

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

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

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

      看下代碼的演示:

 1 class PointerDemo
 3 {
 5   public int x, y;
 7 }

11 class Program 13 { 15   unsafe static void ChangeValue(int* x, int* y) 17   { 19     *x = 200; //修改所在地址值 21     *y = 300; 23   }

27   unsafe static void Main() 29   { 31     var obj = new PointerDemo(); 33     Console.WriteLine("原始值: {0}, {1}", obj.x, obj.y); 37     fixed (int* n = &obj.x) 39     { 41       fixed (int* p = &obj.y) 43       { 45         ChangeValue(n, p); //取data地址並傳遞 47       } 49     } 53     Console.WriteLine("改變地址后: {0}, {1}", obj.x, obj.y); 57     Console.ReadLine(); 59   } 61 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM