C# 手動管理內存

news/2025/11/3 3:28:10/文章来源:https://www.cnblogs.com/yugawakun/p/19185735

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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/953970.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 委託(Delegate)與事件(Event)筆記

C# 委託(Delegate)與事件(Event)筆記📝 C# 委託(Delegate)與事件(Event)筆記 1️⃣ 委託(Delegate) 定義委託是一種方法指標(方法的變數),可以存放、傳遞方法。// 定義委託 delegate void MyDelegate(s…

点特征 - MKT

点特征 核心差异与总结维度与信息层次的不同:ORB和BSC是局部描述符: 它们只描述一个点周围的非常局部的信息(纹理或几何)。它们不知道这个点属于“椅子”还是“桌子”。 KPConv特征是点特征: 它是在整个点云的上下…

正弦化作用 - MKT

正弦化作用是谁最新想到这个正弦化处理,怎么想到的?这是一个非常深刻的问题,触及了深度学习领域一个精彩的创新故事。这个想法的出现不是一蹴而就的,而是一个演进的过程。简单来说,最先将正弦函数用于编码连续信息…

不同域的阿里邮箱 跨域搬家方法

================# 水平有限 欢迎指正 #=================

第三节课内容,dos的部分基础命令

mod应用 打开开始+系统+命令提示符 win+R(建议,且最喜欢使用) 选择任意文件,shift+鼠标右键,打开命令行窗口 在资源管理器中,任意文件链接前加上cmd路径(管理员方式运行,选择以管理员方式运行)常用的dos命令盘…

OK3506-S12 Mini开发板+基本使用环境配置

OK3506-S12 Mini开发板开箱和基本使用(飞凌嵌入式) 开箱包裹内容打开包装,你可以看到以下物品usb typec线 OK3506-S12 Mini开发板图1 OK3506-S12 Mini开发板图2 OK3506-S12 Mini开发板 开发板简介RK3506J/RK3506B是…

C#中异常处理的使用例子 - 开源研究系列文章

C#中异常处理的使用例子 - 开源研究系列文章Posted on 2025-11-03 00:30 lzhdim 阅读(0) 评论(0) 收藏 举报 应用的异常处理在应用里是比较常见的使用,一般情况下尽量不使用try-catch来捕获异常并处理,而…

windows系统Ollama私有化模型部署

windows系统Ollama私有化模型部署 一.安装Ollama 在官网下载https://ollama.com/download

【UE工具向】如何优雅的扩展DataTable ToolBar

如何优雅的向DataTable上方ToolBar区域新增功能按钮 近期终于抽出空来把之前做的一些小东西整理出来,希望能对你有帮助问题背景:只要是大量使用DT的项目我想都会遇到想要"一键处理XXX"的需求,比如是一键打…

亲爱的伊利斯

亲爱的伊利斯:人们总说,我写作的时候一定正受着什么折磨,而现在折磨我的人就是你。你的一切让我备受折磨。我想到你的高跟鞋,你的刘海,你闪闪发亮的短靴,你房间窗户下镶着一排小石头的拖鞋。我想到你的手指按电视…

go清单

golang 中 make 和 new 的区别? for range 的时候它的地址会发生变化么? 能介绍下 rune 类型吗? 调用函数传入结构体时,应该传值还是指针? goroutine什么情况下会阻塞? 讲讲 Go 的 select 底层数据结构和一些特性…

MySQL_进阶

存储引擎MySQl体系结构存储引擎简介存储引擎特点存储引擎的选择

团队项目1-团队展示选题-星瀚餐递

项目 内容所属课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience作业要求 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13471作业目标 介绍团队基本情况,确…

2025-11-02 闲话

2025-11-02 闲话浅析狗叫行为。 今天读了一下李新野的新 latex pdf 《人妻约会指南》。不得不让我回顾我自己和异性的 social 行为。我听说有些朋友是不太需要和异性 social 的,我认为我好像还不是这样。 我认为我不能…

DRL-SARSA

SARSA算法 1. 引言 SARSA(State-Action-Reward-State-Action)是一种重要的强化学习算法,属于时序差分(Temporal Difference, TD)控制方法。它通过直接学习动作价值函数Q(s,a)来解决强化学习问题。与Q-learning不同…

2025.10.20~2025.10.26

2025.10.20~2025.10.262022HDU多校08 A 由于只能选择奇数长度的段进行反转,因此奇偶性不同的两个位置永远不能实现交换。 而取长度为 \(3\) 的段总能使相邻两个奇偶性相同的位置进行交换,因此只需对奇子列和偶子列分…

Day10复合选择器

复合选择器分为后代选择器,子代选择器,交集选择器和并集选择器 1.后代选择器即跨过父类,而在该父类下的所有该后代选择器所对应的标签都会被应用 <!DOCTYPE html> <html lang="en"> <head…

2025.10.27~2025.11.02

2025.10.27~2025.11.022022HDU多校09 A Problem \(T\) 组数据。给定一个长为 \(n\) 的数列 \(a\),判断是否能将其重排为数列 \(b\) 使 \(b\) 中不存在 \(1 \le i < j < k \le n \and a_{j} - a_{i} = a_{k} - a…

一次 Windows 内核卡住的调试经历

记录一次 Windows 内核卡住的调试经历一次 Windows 内核卡住的调试经历 今年整了个电脑,本想提升生活游戏体验,却被一个及其影响体验的问题折磨了三个月,后来终于算是得到了解决(规避)。过程是曲折的,结果是比较…

SQCTF-web

SQCTF-web小小查询系统 Upload_Level1 Upload_Level2 baby_rce 无参之舞 千查万别 eeaassyy ez-include 内部威胁情报监控平台 ez-sqli 黑客终端 PHP的XXE PHP的后门 CTF商城 Easy_SQLi EasyMD5 雏形系统 简单越权 inc…