網站首頁 編程語言 正文
stackalloc 表達式
stackalloc
表達式在棧(stack
)上分配內存塊。
在方法執行期間創建的棧中分配的內存塊會在方法返回時自動丟棄。不能顯式釋放使用 stackalloc
分配的內存。stackalloc
分配的內存塊不受垃圾回收的影響,也不必通過 fixed
語句固定。
棧內存,棧內存開辟快速高效但資源有限,通常限制1M。
可以將 stackalloc
表達式的結果分配給以下任一類型的變量:
stackalloc 分配 System.Span<T> 或 System.ReadOnlySpan<T> 類型
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }
將stack分配內存塊
賦值給 System.Span<T>
或 System.ReadOnlySpan<T>
類型的變量不必使用不安全上下文(unsafe context
)。
可以在表達式允許的任何地方使用stackalloc
,并且在需要分配內存
時,推薦盡可能的使用 Span<T>
或 ReadOnlySpan<T>
類型。
int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];
Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 }; var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 }); Console.WriteLine(ind); // output: 1
stackalloc 分配 指針類型
如下示例,對于指針類型,stackalloc
表達式只能用于本地變量聲明的初始化中。
unsafe { int length = 3; int* numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; } }
使用指針類型,必須使用不安全上下文(unsafe context
)。
stackalloc分配內存的注意點
堆棧可用的內存數量是有限的,如果分配太多內存,則可能發生StackOverflowException
異常。因此需要注意以下幾點:
- 限制使用
stackalloc
分配的內存數量。
例如,如果預期的緩沖區大小低于某個限制,則可以在堆棧上分配內存;否則,請使用所需長度的數組。如下代碼所示:
const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];
stack 上可用內存數量取決于代碼的執行環境。
- 避免在循環內部使用
stackalloc
。在循環外部allocate
分配內存塊,并在循環內部重用。
新分配內存的內容是未定義的。必須在使用之前初始化。 比如,可以使用 Span<T>.Clear
方法設置所有的元素項為類型T
的默認值。
也可以使用數組初始化器定義新分配內存的內容。
Span<int> first = stackalloc int[3] { 1, 2, 3 }; Span<int> second = stackalloc int[] { 1, 2, 3 }; ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };
非托管類型 Unmanaged type
在定義指針、stackalloc T[n]
時,其類型只能是非托管類型。(雖然在使用和形式上,非托管類型與C#的原始類型幾乎沒有區別,但,還是可以了解下)。
以下類型的屬于或也屬于非托管類型:
-
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
, orbool
- 任何
enum
類型 - 任何
pointer
類型 - 任何 只包含非托管類型字段的用戶定義(
user-defined
)的struct
類型
使用非托管泛型約束unmanaged
,指定類型參數為非指針、不可為空的非托管類型。
僅包含非托管類型字段的構造結構類型(constructed struct type
)也是非托管的。如下示例所示,DisplaySize<T>()
方法的泛型約束為unmanaged
,在調用時Coords<int>
、Coords<double>
作為非托管類型使用:
using System; public struct Coords<T> { public T X; public T Y; } public class UnmanagedTypes { public static void Main() { DisplaySize<Coords<int>>(); DisplaySize<Coords<double>>(); } private unsafe static void DisplaySize<T>() where T : unmanaged { Console.WriteLine($"{typeof(T)} is unmanaged and its size is {sizeof(T)} bytes"); } } // Output: // Coords`1[System.Int32] is unmanaged and its size is 8 bytes // Coords`1[System.Double] is unmanaged and its size is 16 bytes
泛型結構Coords<T>
可以是非托管和托管構造類型。當然也可以限制為非托管類型,如下:
public struct Coords<T> where T : unmanaged { public T X; public T Y; }
參考
stackalloc expression
Unmanaged types
原文鏈接:https://juejin.cn/post/7175547071594758204
相關推薦
- 2024-01-11 spring 事務控制 設置手動回滾 TransactionAspectSupport.curren
- 2022-11-16 常用的Git便捷操作合集_相關技巧
- 2022-12-28 React?Server?Component混合式渲染問題詳解_React
- 2022-07-25 Android?嵌套?Intent?隱患及解決方案_Android
- 2022-09-10 C++中memcpy函數的使用以及模擬實現_C 語言
- 2023-02-09 C++?類模板與成員函數模板示例解析_C 語言
- 2022-05-03 ASP.NET?Core基于滑動窗口實現限流控制_實用技巧
- 2022-08-25 Python并行編程多線程鎖機制Lock與RLock實現線程同步_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支