stackalloc关键字在堆栈上产生的存储器的区域,并返回一个指针,指向存储器的开始。退出堆栈分配的内存时,将在创建内存的范围退出时自动将其删除。
//分配1024个字节。这将返回一个指向第一个字节的指针。 byte* ptr = stackalloc byte[1024]; //分配一些值... ptr[0] = 109; ptr[1] = 13; ptr[2] = 232; ...
在不安全的上下文中使用。
与C#中的所有指针一样,对读取和赋值也没有边界检查。超出分配的内存范围进行读取将导致无法预料的结果-它可能访问内存中的任意位置,或者可能导致访问冲突异常。
//分配1字节 byte* ptr = stackalloc byte[1]; //不可预测的结果... ptr[10] = 1; ptr[-1] = 2;
退出堆栈分配的内存时,将在创建内存的范围退出时自动将其删除。这意味着您永远都不应返回使用stackalloc创建的内存或将其存储到范围的生存期之外。
unsafe IntPtr Leak() { //在堆栈上分配一些内存 var ptr = stackalloc byte[1024]; //Return a pointer to that memory (this exits the scope of "Leak") return new IntPtr(ptr); } unsafe void Bad() { //ptr现在是一个无效的指针,以任何方式使用它都会有 //不可预测的结果。这与访问超越完全相同 //指针的边界。 var ptr = Leak(); }
stackalloc只能在声明和初始化变量时使用。以下是不正确的:
byte* ptr; ... ptr = stackalloc byte[1024];
备注:
stackalloc应该仅用于性能优化(用于计算或互操作)。这是由于以下事实:
不需要垃圾回收器,因为内存是在堆栈而不是堆上分配的-变量超出范围后立即释放内存
在堆栈而不是堆上分配内存更快
由于数据的局部性,增加了CPU缓存命中的机会