C# 语言stackalloc关键字

示例

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缓存命中的机会

以上是 C# 语言stackalloc关键字 的全部内容, 来源链接: utcz.com/z/343206.html

回到顶部