C#中的Unsafe和Fixed

吞吞吐吐的發表於2017-11-15
託管程式碼 (managed code):由公共語言執行庫環境(而不是直接由作業系統)執行的程式碼。託管程式碼應用程式可以獲得公共語言執行庫服務,例如自動
垃圾回收、執行庫型別檢查和安全支援等。這些服務幫助提供獨立於平臺和語言的、統一的託管程式碼應用程式行為。 非託管程式碼(Unmanaged Code):在公共語言執行庫環境的外部,由作業系統直接執行的程式碼。非託管程式碼必須提供自己的垃圾回收、型別檢查、安全支
持等服務;它與託管程式碼不同,後者從公共語言執行庫中獲得這些服務。
Unsafe的程式碼介於這兩者之間,它也是在CLR的環境中執行,但是我們可以直接操作記憶體。只要我們的程式碼包含下面三個指標操作符之一就需要使用Unsafe
關鍵字:

*
&
->

例如:

unsafe static void ChangeValue(int* pInt)
    {
        *pInt = 23;
    }

上面的程式碼由於是在CLR下託管執行,為了減少記憶體碎片C#的自動垃圾回收機制會允許已經分配的記憶體在執行時進行位置調整,所以如果我們多次呼叫的話就可能
導致指標指向其他的變數。比如*pInt為指向一個變數的地址為1001,CLR在重新記憶體整理分配後該變數就儲存在地址為5001的地方。而原來1001的地方可能會
被分配其他變數,要解決這個問題我們就需要使用Fixed關鍵字。

fixed 語句禁止垃圾回收器重定位可移動的變數。fixed 語句只能出現在不安全的上下文中。Fixed 還可用於建立固定大小的緩衝區。如下面例子:

using System;
class CaryData
{
    public int data;
}

class CProgram
{
   
    unsafe static void ChangeValue(int* pInt)
    {
        *pInt = 23;
    }

    public unsafe static void Main()
    {
        CaryData cd = new CaryData();
        Console.WriteLine("改變前: {0}", cd.data);        

        fixed (int* p = &cd.data)
        {
            ChangeValue(p);
        }
        Console.WriteLine("改變後: {0}", cd.data);
    }
}

注意要勾選專案屬性中生成標籤的允許不安全程式碼。

本文轉自生魚片部落格園部落格,原文連結:http://www.cnblogs.com/carysun/archive/2009/11/07/csharp-unsafe.html,如需轉載請自行聯絡原作者


相關文章