C# 手動管理內存

手動管理內存實驗

本實驗旨在理解 C# 中 unsafe 指標操作與 非託管記憶體(unmanaged memory) 的使用方法,並學會如何使用 NativeMemory.Alloc 分配記憶體、直接操作位元資料、以及使用 Encoding 將 byte 資料正確轉換為字串。

二、實驗環境

  1. 開發工具:JetBrains Rider / Visual Studio 2022
  2. .NET SDK:.NET 8.0
  3. 作業系統:Windows 11 / Linux / macOS
  4. 專案設定:
<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

三、實驗程式碼

using System;
using System.Runtime.InteropServices;
using System.Text;

unsafe
{
    // 分配 100 bytes 非託管記憶體
    void* ptr = NativeMemory.Alloc(100);

    try
    {
        byte* bytes = (byte*)ptr;

        // 將 ASCII 字元 '1', '2', '3' 寫入記憶體
        bytes[0] = (byte)'1';
        bytes[1] = (byte)'2';
        bytes[2] = (byte)'3';
        bytes[3] = (byte)'\0'; // C-style 字串結尾

        // 讀取前 3 bytes 並轉為字串
        string text = Encoding.ASCII.GetString(bytes, 3);

        Console.WriteLine($"輸出內容:{text}");
    }
    finally
    {
        // 釋放非託管記憶體,防止記憶體洩漏
        NativeMemory.Free(ptr);
    }
}

四、實驗步驟

  1. 在 .csproj 檔中啟用 true
  2. 使用 NativeMemory.Alloc(100) 分配 100 bytes 非託管記憶體。
  3. 利用指標 byte* 對該記憶體位置直接操作,寫入字元 '1', '2', '3'。
  4. 透過 Encoding.ASCII.GetString() 將指定長度的 bytes 轉為字串。
  5. 輸出結果後,使用 NativeMemory.Free(ptr) 釋放記憶體。

五、實驗結果

執行後輸出:

輸出內容:123

六、結果分析

步驟 動作說明 結果
NativeMemory.Alloc(100) 分配 100 bytes 未受 GC 管理的空間 成功分配
bytes[0] = (byte)'1' 直接操作指標寫入資料 記憶體內容:31 32 33 00(十六進制)
Encoding.ASCII.GetString(bytes, 3) 將前 3 bytes 轉為字串 "123"
NativeMemory.Free(ptr) 手動釋放非託管記憶體 無洩漏

分析:

  • 若錯誤地使用 bytes->ToString(),則輸出 "49",因為那是 '1' 的 ASCII 數值。
  • 正確轉換方式是透過 Encoding 類別將 byte[] → string。
  • NativeMemory 提供比 Marshal.AllocHGlobal 更現代化的低階記憶體控制 API。
  • 此實驗說明了 unsafe 區塊允許開發者像 C 語言一樣直接控制記憶體。
  1. 本實驗展示了 C# 在 unsafe 環境中對非託管記憶體的操作能力。
  2. 使用 NativeMemory.Alloc 分配記憶體後,可直接透過指標寫入資料。
  3. 透過 Encoding.GetString() 可將指定的 bytes 區段轉換成字串。
  4. 雖然 unsafe 操作提供更高的效能與靈活度,但需開發者自行負責記憶體管理,
  5. 若未釋放記憶體或操作越界,將導致非託管記憶體洩漏或程式崩潰。

✅ 建議:除非在高效能或與原生程式碼互通時,否則應避免大量使用 unsafe。

posted on 2025-11-03 03:26  lamkuanthedev  阅读(4)  评论(0)    收藏  举报

导航