首页 >后端开发 >C++ >堆或堆栈:'new”在哪里为 C# 结构分配内存?

堆或堆栈:'new”在哪里为 C# 结构分配内存?

DDD
DDD原创
2025-01-13 15:16:41688浏览

Heap or Stack: Where Does `new` Allocate Memory for a C# Struct?

C# 中使用 "new" 关键字创建结构体时,内存分配在堆还是栈上?

使用 "new" 运算符创建类实例时,内存分配在堆上。但使用 "new" 运算符创建结构体实例时,内存分配在哪里呢?

栈内存与堆内存

栈是一种用于在程序执行期间存储局部变量和方法调用的数据结构。它是一种后进先出 (LIFO) 结构,这意味着最近分配的内存最先被移除。

堆是一个动态内存空间,根据需要创建和分配对象。与栈不同,它不遵循内存分配的特定顺序。

使用 "new" 关键字创建结构体的内存分配

对于结构体,使用 "new" 运算符时,需要考虑两种情况:

  1. 无参数构造函数 (new Guid();):

    • 使用 "new" 运算符和无参数构造函数会在 上分配结构体的内存。
    • 这是因为 C# 编译器将无参数构造函数视为一种特殊情况,将其视为零初始化操作。
    • 因此,会在堆上创建一个新的内存位置,并在其中构造结构体。
  2. 带参数构造函数 (new Guid(someString);):

    • 使用 "new" 运算符和带参数构造函数会在 上分配内存用于临时存储。
    • 构造函数初始化结构体后,分配的栈内存将被丢弃。
    • 此过程与将实例化的结构体赋值给局部变量不同,后者会在堆上分配内存,就像无参数构造函数一样。

IL 代码生成

为了理解幕后行为,让我们检查 C# 编译器生成的中间语言 (IL) 代码:

  • newobj 指令在栈上分配空间并为中间值(例如,方法参数)调用带参数的构造函数。
  • call instance 指令使用带参数的构造函数初始化已分配的存储位置(栈或堆)。
  • initobj 指令初始化已分配的存储位置(栈或堆),将其内容清零(用于无参数构造函数调用)。

结论

总之,与始终在堆上分配内存的类实例不同,对结构体使用 "new" 运算符会在无参数构造函数的情况下在堆上分配内存,在带参数构造函数的情况下在栈上分配内存(用于临时存储)。此行为反映在生成的 IL 代码中,并提供了对底层内存管理过程的深入了解。

以上是堆或堆栈:'new”在哪里为 C# 结构分配内存?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn